ping-pong-req.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. //
  2. // Copyright (c) 2019-2022 Ivan Baidakou (basiliscos) (the dot dmol at gmail dot com)
  3. //
  4. // Distributed under the MIT Software License
  5. //
  6. #include <rotor/ev.hpp>
  7. #include <iostream>
  8. #include <random>
  9. #include <boost/asio/detail/winsock_init.hpp> // for calling WSAStartup on Windows
  10. namespace payload {
  11. struct pong_t {};
  12. struct ping_t {
  13. using response_t = pong_t;
  14. };
  15. } // namespace payload
  16. namespace message {
  17. using ping_t = rotor::request_traits_t<payload::ping_t>::request::message_t;
  18. using pong_t = rotor::request_traits_t<payload::ping_t>::response::message_t;
  19. } // namespace message
  20. struct pinger_t : public rotor::actor_base_t {
  21. using rotor::actor_base_t::actor_base_t;
  22. void set_ponger_addr(const rotor::address_ptr_t &addr) { ponger_addr = addr; }
  23. void configure(rotor::plugin::plugin_base_t &plugin) noexcept override {
  24. rotor::actor_base_t::configure(plugin);
  25. plugin.with_casted<rotor::plugin::starter_plugin_t>([](auto &p) { p.subscribe_actor(&pinger_t::on_pong); });
  26. }
  27. void on_start() noexcept override {
  28. rotor::actor_base_t::on_start();
  29. request<payload::ping_t>(ponger_addr).send(rotor::pt::seconds(1));
  30. }
  31. void on_pong(message::pong_t &msg) noexcept {
  32. auto &ec = msg.payload.ee;
  33. if (!ec) {
  34. std::cout << "pong received\n";
  35. } else {
  36. std::cout << "pong was NOT received: " << ec->message() << "\n";
  37. }
  38. do_shutdown();
  39. }
  40. rotor::address_ptr_t ponger_addr;
  41. };
  42. struct ponger_t : public rotor::actor_base_t {
  43. using generator_t = std::mt19937;
  44. using distribution_t = std::uniform_real_distribution<double>;
  45. std::random_device rd;
  46. generator_t gen;
  47. distribution_t dist;
  48. explicit ponger_t(config_t &cfg) : rotor::actor_base_t(cfg), gen(rd()) {}
  49. void configure(rotor::plugin::plugin_base_t &plugin) noexcept override {
  50. rotor::actor_base_t::configure(plugin);
  51. plugin.with_casted<rotor::plugin::starter_plugin_t>([](auto &p) { p.subscribe_actor(&ponger_t::on_ping); });
  52. }
  53. void on_ping(message::ping_t &req) noexcept {
  54. auto dice = dist(gen);
  55. std::cout << "pong, dice = " << dice << std::endl;
  56. if (dice > 0.5) {
  57. reply_to(req);
  58. }
  59. }
  60. };
  61. int main() {
  62. try {
  63. auto *loop = ev_loop_new(0);
  64. auto system_context = rotor::ev::system_context_ptr_t{new rotor::ev::system_context_ev_t()};
  65. auto timeout = boost::posix_time::milliseconds{10};
  66. auto sup = system_context->create_supervisor<rotor::ev::supervisor_ev_t>()
  67. .loop(loop)
  68. .loop_ownership(true) /* let supervisor takes ownership on the loop */
  69. .timeout(timeout)
  70. .finish();
  71. auto pinger = sup->create_actor<pinger_t>().timeout(timeout).autoshutdown_supervisor().finish();
  72. auto ponger = sup->create_actor<ponger_t>().timeout(timeout).finish();
  73. pinger->set_ponger_addr(ponger->get_address());
  74. sup->start();
  75. ev_run(loop);
  76. } catch (const std::exception &ex) {
  77. std::cout << "exception : " << ex.what();
  78. }
  79. std::cout << "exiting...\n";
  80. return 0;
  81. }