After reading the documentation here and here, specifically this paragraph
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.
I think you can use null_buffers
for every zmq_pollitem_t
and defer the event loop to an io_service
, completely bypassing zmq_poll()
altogether. There appear to be some caveats in the aforementioned documentation however, notably
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.
So when the handler for one of your zmq sockets is fired, you'll have to do a little more work before handling the event I think. Uncompiled pseudo-code is below
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
}
}
);
note you don't have to use a lambda here, boost::bind
to a member function would be sufficient.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…