一段时间后zmq套接字无法正常工作

时间:2015-01-31 13:21:17

标签: c++ network-programming zeromq publish-subscribe

我有一个程序,其中客户端有一个ZMQ_SUB套接字,服务器端有一个ZMQ_PUB套接字,客户端订阅服务器:

相当简单的代码:

客户方:

zmq::socket_t subscriber(context, ZMQ_SUB);     
subscriber.connect("tcp://xxx:xxx");    
subscriber.setsockopt(ZMQ_SUBSCRIBE, "", 0);

服务器端:

zmq::socket_t publisher(zmqContext, ZMQ_PUB);
publisher->bind("tcp://*.xxx");

我在客户端和服务器之间使用另一对ZMQ_REQ,ZMQ_REP套接字。每次客户端通过ZMQ_REQ套接字向服务器发送一些请求时,服务器通过ZMQ_REP套接字接收它,做一些工作,通过REP套接字响应,同时生成一堆消息,并通过ZMQ_PUB发布它们插座。

大多数情况下,客户端能够从ZMQ_SUB套接字接收消息,但我确实遇到客户端没有收到这些消息的情况。

保证在服务器端生成消息,并在生成后立即发布消息。

这是正常的吗?或者我的使用/设置有问题,导致这种不确定行为。 (客户端SUB套接字有时不接收消息)

1 个答案:

答案 0 :(得分:1)

这是正常的吗?

这样的问题很容易被问到,但很难得到答案而没有其他细节和背景。

ZeroMQ “缺少消息问题”这篇伟大的Pieter HINTJENS书中的章节"Code Connected Volume 1"说了一些关于这个主题的一般原则:< / p>


•在SUB套接字上,使用zmq_setsockopt()使用ZMQ_SUBSCRIBE设置订阅,否则您将无法收到消息。因为您通过前缀订阅消息,所以如果您订阅""(空订阅),您将获得所有内容。

•如果在SUB套接字开始发送数据后启动PUB套接字(即建立与PUB套接字的连接),您将丢失之前发布的内容建立了联系。如果这是一个问题,请设置您的体系结构,以便首先启动SUB套接字,然后PUB套接字开始发布。

•即使同步SUBPUB套接字,您仍可能丢失消息。这是因为在实际创建连接之前不会创建内部队列。如果您可以切换bind / connect方向以便SUB套接字bind - s和PUB套接字connect - s,那么可能会发现它比你期望的更有效。

•如果您使用的是REPREQ套接字,并且您没有坚持同步send / recv / send / { {1}}订单,ØMQ将报告您可能忽略的错误。然后,看起来你会丢失消息。如果您使用recvREQ,请坚持REP / send订单,并始终在实际代码中检查ØMQ呼叫上的错误。

•如果您正在使用recv套接字,您会发现要连接的第一个PUSH套接字将获取不公平的消息份额。只有在成功连接所有PULL个套接字时才会发生消息的准确轮换,这可能需要几毫秒。作为PULL / PUSH的替代方案,对于较低的数据速率,请考虑使用PULL / ROUTER和负载均衡模式。

•如果您跨线程共享套接字,则不要。它会导致随机的怪异和崩溃。

•如果您使用的是DEALER,请确保两个套接字位于同一个inproc。否则连接端实际上会失败。此外,context首先是bind,然后是connectinproc不是tcp之类的断开连接的传输。

•如果您正在使用ROUTER套接字,则通过发送格式错误的身份框架(或忘记send身份框架),非常容易意外丢失邮件。一般来说,设置ZMQ_ROUTER_MANDATORY套接字上的ROUTER选项是个好主意,但也要检查每次send次呼叫的返回代码。

•最后,如果你真的无法弄清楚出了什么问题,制作一个可以重现问题的最小测试用例,并向ØMQ社区寻求帮助。