我正在使用zmq,但在文档和示例中找不到正确使用以下套接字选项的答案:
- ZMQ_HEARTBEAT_IVL
- ZMQ HEARTBEAT_TIMEOUT
- ZMQ_HEARTBEAT_TTL
文档指出,它们可以与任何套接字类型一起使用("当使用面向连接的传输时"(。有没有办法将它们与REQ/REP套接字对一起使用?
测试客户端代码:
zmq::context_t context( 1 );
zmq::socket_t client( context, ZMQ_REQ );
client.connect( "tcp://localhost:5555" );
// Send request.
std::string request( "test message" );
zmq::message_t message( string.size() );
memcpy( message.data(), string.data(), string.size() );
socket.send( message, flags );
// Wait for reply.
socket.recv( &message );
// Do some work that takes cca 10 secs.
// ...
delete client;
测试服务器代码:
zmq::context_t context( 1 );
zmq::socket_t server( context, zmq::socket_type::rep );
//server.set( zmq::sockopt::rcvtimeo, 5000 );
server.set( zmq::sockopt::heartbeat_ivl, 1000 );
server.set( zmq::sockopt::heartbeat_timeout, 3000 );
server.set( zmq::sockopt::heartbeat_ttl, 3000 );
server.bind( "tcp://*:5555" );
// Wait for request.
zmq::message_t message;
server.recv( &message );
// Send reply.
zmq::message_t message2("Test reply.", 11);
server.send( message);
// Wait for new request.
server.recv( &message );
// ...
我的目标是在客户端完成后结束服务器端。套接字选项zmq::sockopt::rcvtimeo
运行良好,它关闭了服务器端的连接。我认为心跳套接字选项会导致类似的情况,我的意思是在客户端完成工作后关闭服务器,而不是更早。我在服务器端和客户端尝试了所有可能的组合,但服务器端总是陷入第二个recv
操作。使用Wireshark检查本地主机网络流量告诉乒乓消息已经传递,但仅此而已。
所以我的问题是:
- 这些套接字选项可以用于REQ/REP连接吗
- 如果是,那么怎么做?哪一侧应设置这些插座选项
- 如果没有,那么建议使用哪些插座类型
提前感谢!
好的,所以看起来您需要使用zmq_socket_monitor((函数。这会导致上下文为自己创建一个ZMQ_PAIR套接字,并将其绑定到您指定的端点。您必须创建自己的ZMQ_PAIR套接字,并将其连接到该端点。
您可以从ZMQ_PAIR套接字读取事件消息(有关如何格式化这些消息,请参阅api参考(。因此,您可以在对zmq_poll((的调用中包含该PAIR套接字,这样,当您在zmq_socket_monitor((调用中引用的套接字的状态发生更改时,您的应用程序就可以得到异步通知。
我认为,将报告的心跳超时事件是ZMQ_event_DISCONNECTED。
请参见此处。
我想说的是,为了从中获得最大的价值,您几乎必须使用zmq_poll(((或类似的(。例如,期望接收消息的客户端不能在从连接到服务器的套接字调用zmq_recv((时被阻止,也不能在从监视器zmq_PAIR套接字调用zmmq_recv(时被阻挡。然而,如果您在等待服务器和监视器套接字的zmq_poll((调用中被阻止,那么当有来自服务器的消息时,或者出现了一些问题,意味着您将无法获得消息时,就会返回该消息。