zeromq:重置REQ/REP套接字状态

fra*_*ans 9 c++ sockets zeromq

当您使用简单的ZeroMQ REQ/REP模式时,您依赖于固定的send() - > recv()/ recv() - > send()序列.由于文章描述你遇到麻烦时,参与者的请求的中间断开,因为你不能只是开始了与另一个连接接收的下一个请求,但状态机将迫使你的请求发送到一个断开.

自上述文章撰写以来,是否有更优雅的方法来解决这个问题?

重新连接解决此问题的唯一方法(除了不使用REQ/REP但使用其他模式)

Viv*_*ger 25

由于公认的答案对我来说非常难过,我做了一些研究,发现我们需要的一切实际上都在文档中.

.setsockopt()用正确的参数可以帮助你重新设置您的套接字状态机没有惨遭摧毁它,重建另一个比上一个人死亡的身体上.

(是的,我喜欢这个形象).

ZMQ_REQ_CORRELATE:匹配对请求
的回复REQ套接字的默认行为是依赖于消息的排序来匹配请求和响应,这通常就足够了.当此选项设置为时1,REQ套接字将使用包含请求的额外帧为外发消息添加前缀id.这意味着完整的消息是(请求id,identity,0,user frames…).该REQ插座将丢弃不与这两个帧开头的所有传入的消息.
选项值类型 int
选项值单位 0,1
默认值 0
适用的套接字类型 放宽请求和回复之间的严格交替 默认情况下,套接字不允许在收到对前一个请求的回复之前启动新请求.设置为时,允许发送另一条消息,并且具有断开与期望回复的对等方的基础连接的效果,从而触发对支持它的传输的重新连接尝试.重置请求 - 回复状态机,并向下一个可用对等体发送新请求. 如果设置为,则还启用以确保请求和回复的正确匹配.否则,可以将对中止请求的延迟回复报告为对取代请求的回复. 选项值类型 选项值单位 , 默认值 适用的套接字类型 ZMQ_REQ

ZMQ_REQ_RELAXED:
REQzmq_send(3)1
1ZMQ_REQ_CORRELATE
int
01
0
ZMQ_REQ

这里有完整的文档


use*_*307 7

好消息是,从ZMQ 3.0及更高版本(现代)开始,您可以在套接字上设置超时.正如其他人在其他地方所述,您必须在创建套接字后,但在连接它之前执行此操作:

zmq_req_socket.setsockopt( zmq.RCVTIMEO, 500 ) # milliseconds

然后,当您实际尝试接收回复时(在向REP套接字发送消息之后),您可以捕获超出超时时将断言的错误:

 try:
   send( message, 0 )
   send_failed = False

 except zmq.Again:
   logging.warning( "Image send failed." )
   send_failed = True
Run Code Online (Sandbox Code Playgroud)

然而!当发生这种情况时,正如在别处观察到的那样,你的套接字将处于一个有趣的状态,因为它仍然会期待响应.此时,除了重新启动套接字之外,我找不到任何可靠的工作方式.请注意,如果断开()套接字然后重新连接()它,它仍将处于这种不良状态.因此你需要

def reset_my_socket:
  zmq_req_socket.close()
  zmq_req_socket = zmq_context.socket( zmq.REQ )
  zmq_req_socket.setsockopt( zmq.RCVTIMEO, 500 ) # milliseconds
  zmq_req_socket.connect( zmq_endpoint )
Run Code Online (Sandbox Code Playgroud)

您还会注意到因为我关闭()d套接字,接收超时选项"丢失",所以在新套接字上设置它是很重要的.

我希望这有帮助.我希望这不会成为这个问题的最佳答案.:)