diff --git a/examples/client/main.cpp b/examples/client/main.cpp index 6e5abaa..f3f0491 100644 --- a/examples/client/main.cpp +++ b/examples/client/main.cpp @@ -354,12 +354,35 @@ void test_callback() { std::cin >> str; } +void wait_for_notification(rpc_client& client) { + client.async_call<0>("sub", [&client](const boost::system::error_code & ec, string_view data) { + auto str = as(data); + std::cout << str << '\n'; + + wait_for_notification(client); + }); +} + +void test_sub() { + rpc_client client; + bool r = client.connect("127.0.0.1", 9000); + if (!r) { + return; + } + + wait_for_notification(client); + + std::string str; + std::cin >> str; +} + int main() { test_callback(); test_echo(); test_sync_client(); test_async_client(); + //test_sub(); //test_call_with_timeout(); //test_connect(); //test_upload(); diff --git a/examples/server/main.cpp b/examples/server/main.cpp index 4394a9b..8a45ab6 100644 --- a/examples/server/main.cpp +++ b/examples/server/main.cpp @@ -85,6 +85,57 @@ std::string echo(rpc_conn conn, const std::string& src) { return src; } +struct notifier { +public: + notifier() { + std::thread thd([this] { + while (!stop_) { + if (has_subs_) { + notify("this a notification from the server"); + } + + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + }); + thd.detach(); + } + + ~notifier() { + stop_ = true; + } + + void sub(rpc_conn conn) { + if (!has_subs_) { + has_subs_ = true; + } + auto req_id = conn.lock()->request_id(); + std::unique_lock lock(mtx_); + subs_.emplace_back(conn, req_id); + } + +private: + void notify(const std::string& result) { + { + std::unique_lock lock(mtx_); + for (auto& pair : subs_) { + auto sp_conn = pair.first.lock(); + if (sp_conn) { + sp_conn->pack_and_response(pair.second, result); + } + } + + subs_.clear(); + } + + has_subs_ = false; + } + + std::vector> subs_; + std::mutex mtx_; + std::atomic_bool has_subs_ = { false }; + bool stop_ = false; +}; + int main() { rpc_server server(9000, std::thread::hardware_concurrency()); @@ -100,6 +151,9 @@ int main() { server.register_handler("async_echo", async_echo); server.register_handler("echo", echo); + notifier n; + server.register_handler("sub", ¬ifier::sub, &n); + server.run(); std::string str;