qicosmos / rest_rpc

modern C++(C++11), simple, easy to use rpc framework
MIT License
1.66k stars 365 forks source link

请问服务端不能在接口调用处理过程中pub吗 #86

Open djcxym opened 1 year ago

djcxym commented 1 year ago

在服务端的处理过程中pub会失败,客户端收不到,代码大概如下: image 这个场景应该用处比较大,比如执行一个耗时操作,过程中需要通知进度或其它事件。 请问下,目前是不支持这种操作吗?如果不支持,这种场景应该怎么解决

qicosmos commented 1 year ago

上面这样不行,改成在一个单独的线程里去publish,原因是因为handler的回调是在IO线程里,你写的这个代码实际上把IO线程阻塞了。

djcxym commented 1 year ago

image 即使这样也不行,我发现只要有未返回的接口调用,pub就不生效 跟了下,大概是这里的writequeu size大于1直接返回了 image

djcxym commented 1 year ago

具体场景就是在一个耗时操作中间需要通知一些诸如进度之类的事件

qicosmos commented 1 year ago

代码写得不对,上面那个while死循环了,下面那个thd会析构的,应该用个成员变量的thd

djcxym commented 1 year ago

下面是server.run啊,怎么会析构?pub能收到一次 如果这样不对的话应该怎么写?

qicosmos commented 1 year ago

server端:

    server.register_handler("hello", [&](rpc_conn conn, const std::string &str){
      std::thread thd([&server] {
          person p{1, "tom", 20};
          while (true) {
              server.publish("key", "hello subscriber");
              auto list = server.get_token_list();
              for (auto &token : list) {
                  server.publish_by_token("key", token, p);
                  server.publish_by_token("key1", token, "hello subscriber1");
              }
              std::this_thread::sleep_for(std::chrono::milliseconds(500));
          }
      });
      thd.detach();
      return str;
  });

client端:

  auto result = client.call<std::string>("hello", "world");
  std::cout << result << std::endl;

  client.subscribe("key", [](string_view data) { std::cout << data << "\n"; });
qicosmos commented 1 year ago

另外,这只是测试代码,每调用一次hello都会创建一个线程,实际上可以用一个成员变量的线程,避免每次都创建线程。

djcxym commented 1 year ago

这样相当于调用hello就直接返回了不会耗时,但是这样就得另想办法判断这个耗时操作什么时候完成了,感觉不是很自然。这样操作只能算是【不能在调用过程中pub】的一种workaround,没有别的更好的解法了吗

image

我尝试了下把这里writequeue.size() > 1判断去掉,这样倒是可以一直pub,但是pub快了内存会暴涨

qicosmos commented 1 year ago

回调的handler在io线程里,这个io线程不能被阻塞,如果你的handler里面有耗时的操作就放到线程池里,线程池处理完了再响应,你看下example里面怎么在线程里处理消息的例子吧:https://github.com/qicosmos/rest_rpc/blob/master/examples/server/main.cpp#L78