我有一个使用 ZeroMQ 进行消息传递的 C++ 应用程序。但它还必须为基于 AJAX/Comet 的 Web 服务提供 SGCI 连接。
为此,我需要一个普通的 TCP 套接字。我可以通过普通的 Posix 套接字来做到这一点,但是为了保持跨平台的便携性并让我的生活更轻松(我希望......)我正在考虑使用 Boost::ASIO。
但是现在我遇到了 ZMQ 的冲突,想要使用它自己的 zmq_poll()
和 ASIO 它是 io_service.run()
...
有没有办法让ASIO与0MQ zmq_poll()
一起工作?
或者是否有其他推荐的方法来实现这样的设置?
注意:我可以通过使用多个线程来解决这个问题 - 但它只是一个小的单核/CPU 机器,它会以非常低的 SCGI 流量运行该程序,所以多线程会浪费资源......
最佳答案
ZMQ_FD: Retrieve file descriptor associated with the socket The ZMQ_FD option shall retrieve the file descriptor associated with the specified socket. The returned file descriptor can be used to integrate the socket into an existing event loop; the ØMQ library shall signal any pending events on the socket in an edge-triggered fashion by making the file descriptor become ready for reading.
我认为你可以使用 null_buffers
对于每个 zmq_pollitem_t
并将事件循环推迟到 io_service
,完全绕过 zmq_poll()
。然而,上述文档中似乎有一些警告,特别是
The ability to read from the returned file descriptor does not necessarily indicate that messages are available to be read from, or can be written to, the underlying socket; applications must retrieve the actual event state with a subsequent retrieval of the ZMQ_EVENTS option.
因此,当您的一个 zmq 套接字的处理程序被触发时,您必须在处理我认为的事件之前做更多的工作。未编译的伪代码如下
const int fd = getZmqDescriptorSomehow();
boost::asio::posix::stream_descriptor socket( _io_service, fd );
socket->async_read_some(
boost::asio::null_buffers(),
[=](const boost::system::error_code& error)
{
if (!error) {
// handle data ready to be read
}
}
);
请注意,您不必在这里使用 lambda,boost::bind
到成员函数就足够了。
关于c++ - 将 ZeroMQ 与 Boost::ASIO 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12829005/