diff --git a/include/rest_rpc/router.h b/include/rest_rpc/router.h index bd1449c..e4bf9b1 100644 --- a/include/rest_rpc/router.h +++ b/include/rest_rpc/router.h @@ -21,21 +21,45 @@ struct route_result_t { std::string result; }; +template class helper_t { +public: + helper_t(Tuple &tp) : tp_(tp) {} + + void operator()() {} + +private: + Tuple &tp_; +}; + +template class helper_t { +public: + helper_t(Tuple &tp) : tp_(tp) {} + + void operator()() { + auto &arg = std::get::value - 1>(tp_); + msgpack_codec codec; + arg = codec.unpack(arg.data(), arg.size()); + } + +private: + Tuple &tp_; +}; + class router : asio::noncopyable { public: - template - void register_handler(std::string const &name, Function f) { + template + void register_handler(std::string const &name, Function f, bool pub = false) { uint32_t key = MD5::MD5Hash32(name.data()); key2func_name_.emplace(key, name); - return register_nonmember_func(key, std::move(f)); + return register_nonmember_func(key, std::move(f)); } - template + template void register_handler(std::string const &name, const Function &f, Self *self) { uint32_t key = MD5::MD5Hash32(name.data()); key2func_name_.emplace(key, name); - return register_member_func(key, f, self); + return register_member_func(key, f, self); } void remove_handler(std::string const &name) { @@ -154,7 +178,7 @@ class router : asio::noncopyable { result = msgpack_codec::pack_args_str(result_code::OK, r); } - template + template void register_nonmember_func(uint32_t key, Function f) { this->map_invokers_[key] = [f](std::weak_ptr conn, nonstd::string_view str, @@ -163,6 +187,7 @@ class router : asio::noncopyable { msgpack_codec codec; try { auto tp = codec.unpack(str.data(), str.size()); + helper_t{tp}(); call(f, conn, result, std::move(tp)); } catch (std::invalid_argument &e) { result = codec.pack_args_str(result_code::FAIL, e.what()); @@ -172,7 +197,7 @@ class router : asio::noncopyable { }; } - template + template void register_member_func(uint32_t key, const Function &f, Self *self) { this->map_invokers_[key] = [f, self](std::weak_ptr conn, nonstd::string_view str, @@ -181,6 +206,7 @@ class router : asio::noncopyable { msgpack_codec codec; try { auto tp = codec.unpack(str.data(), str.size()); + helper_t{tp}(); call_member(f, self, conn, result, std::move(tp)); } catch (std::invalid_argument &e) { result = codec.pack_args_str(result_code::FAIL, e.what()); diff --git a/include/rest_rpc/rpc_server.h b/include/rest_rpc/rpc_server.h index 28f3126..11fcfa0 100644 --- a/include/rest_rpc/rpc_server.h +++ b/include/rest_rpc/rpc_server.h @@ -52,15 +52,15 @@ class rpc_server : private asio::noncopyable { void run() { io_service_pool_.run(); } - template + template void register_handler(std::string const &name, const Function &f) { - router_.register_handler(name, f); + router_.register_handler(name, f); } - template + template void register_handler(std::string const &name, const Function &f, Self *self) { - router_.register_handler(name, f, self); + router_.register_handler(name, f, self); } void set_conn_timeout_callback(std::function callback) { diff --git a/tests/test_rest_rpc.cpp b/tests/test_rest_rpc.cpp index 9b7f291..f3048a5 100644 --- a/tests/test_rest_rpc.cpp +++ b/tests/test_rest_rpc.cpp @@ -204,11 +204,12 @@ TEST_CASE("test_client_async_call_with_timeout") { TEST_CASE("test_client_subscribe") { rpc_server server(9000, std::thread::hardware_concurrency()); - server.register_handler("publish", - [&server](rpc_conn conn, std::string key, - std::string token, std::string val) { - server.publish(std::move(key), std::move(val)); - }); + server.register_handler( + "publish", [&server](rpc_conn conn, std::string key, std::string token, + std::string val) { + CHECK(val == "hello subscriber"); + server.publish(std::move(key), std::move(val)); + }); bool stop = false; std::thread thd([&server, &stop] { while (!stop) { @@ -221,6 +222,8 @@ TEST_CASE("test_client_subscribe") { rpc_client client; bool r = client.connect("127.0.0.1", 9000); CHECK(r); + client.publish("key", "hello subscriber"); + client.subscribe("key", [&stop](string_view data) { std::cout << data << "\n"; CHECK_EQ(data, "hello subscriber");