您也许可以使用 XPUB/XSUB 与 REQ/REP 合作执行某些操作。
这些可以永久设置,即客户端和服务器都在同一个 XPUB/XSUB 连接上。当客户端想要发出请求时,它可以通过其 XSUB 套接字发送客户端唯一的订阅消息。服务器读取并记住它。然后,客户端发送一个 REQ,其中再次包含订阅消息作为请求的字段之一。服务器在 REP 上做出响应,并且所有进一步的服务器响应都通过其 XPUB 发送,使用它之前从客户端收到的订阅消息来标记响应。所有其他未订阅的客户将不会收到不适合自己的响应。然后,客户端通过其 XSUB 套接字发送取消订阅,从而取消订阅这些响应(在收到最后一个响应之后;服务器可能必须在最后一个响应中包含“最后一个响应”标志)。对于下一个请求,它使用不同的客户端唯一 ID,以便将该请求的响应与上一个请求的响应区分开来。
这仍然不是非常优雅,但至少它不会一直设置/拆除套接字连接。
伪代码 - 服务器。您需要阅读本指南的这一部分:Pub-Sub Message Envelopes
while (run)
zmq_poll(XPUB socket, X REP socket)
if (ZPUB socket ready)
zmq_recv(client subscription message)
if (message was a subscription)
store subscription info (i.e. the client's unique topic for responses)
else if (message was unsubscribe)
forget client's unique topic for responses
else if (X REP socket ready AND client unique topic received)
zmq_recv(client request including client topic for responses)
process the request
zmq_send(REP socket, first response)
s_sendmore(XPUB socket, client's unique topic for responses)
s_send(XPUB socket, second response)
s_sendmore(XPUB socket, client's unique topic for responses)
s_send(XPUB socket, third response)
else if (X REP socket ready AND client unique topic *not* received)
error condition
end if
loop
和客户
create unique topic for response (a random, unique string) // Caution - I think there's a length limit
zmq_send(ZSUB socket, '\0x01`+ unique topic string)
zmq_setsockopt(ZSUB socket, ZMQ_SUBSCRIBE, unique topic for responses) // may not be necessary - it's a ZSUB socket, and the socket may have already picked this up from the previous zmq_send().
zmq_send(REQ socket, request including unique topic string)
zmq_recv(REQ socket, first response)
zmq_recv(ZSUB socket, second response)
zmq_recv(ZSUB socket, third response)
zmq_setsockopt(ZSUB socket, ZMQ_UNSUBSCRIBE, unique topic for responses) // this may not be necessary, and the follow line might do the same thing
zmq_send(ZSUB socket, '\0x00`+ unique topic string)