zeromq:如何进行REQ-multiple-REP?

时间:2020-04-05 12:59:15

标签: zeromq

使用zeromq,我基本上想做一个'REQ-multiple-REP'模式:客户端向服务器发送1条消息,然后服务器发送多个答复直到完成。 “多次答复”是对该客户的 :不是一般的发布。

我可以自己介绍一下:拥有一个普通的REQ-REP套接字,当服务器收到请求时,它将创建一个新的PUB,并在回复客户端时用该PUB的地址进行回复,然后客户端再进行SUB服务器已经开始将消息放入PUB中。

但这感觉很笨拙。有没有更好的办法?在此用例中,zeromq是否已有一些不错的选择?

2 个答案:

答案 0 :(得分:1)

您可能可以通过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)

答案 1 :(得分:1)

“经销商/路由器”对应该适用于您的用例,其中“请求”由“经销商”代替,“路由器”由“答复”代替。

重要的部分是路由器套接字行为。任何传入的邮件都是多部分的,并且至少包含1个“路由”帧,1个空帧以及发送的内容帧。

发给经销商的任何消息都会弹出第一帧,并使用该帧来确定将消息发送给哪个客户端。