Возможно, вы сможете что-то сделать с XPUB / XSUB, поддерживающим REQ / REP.
Они могут быть установлены постоянно, т. Е. Клиенты и сервер находятся в одном соединении XPUB / XSUB. Когда клиент хочет сделать запрос, он может отправить уникальное клиентское сообщение подписки через свой сокет XSUB. Сервер читает это и запоминает это. Затем клиент отправляет REQ, который снова включает сообщение о подписке в качестве одного из полей запроса. Сервер отвечает на REP, и все дальнейшие ответы сервера отправляются через его XPUB с использованием сообщения подписки, которое он ранее получил от клиента, для маркировки ответов. Все остальные клиенты, не подписанные на это, не будут получать ответы, не предназначенные для них. Затем клиент отписывается от этих ответов (после получения последнего; серверу, возможно, придется включить флаг «последний ответ» в этот последний), отправив сообщение о неполадке через свой сокет XSUB. Для следующего запроса он использует другой уникальный идентификатор клиента, так что ответы на этот запрос можно отличить от ответов на предыдущий запрос.
Это все еще не очень элегантно, но по крайней мере это не настройка все время соединения / разрыв соединений.
Псевдокод - сервер. Вам необходимо прочитать этот раздел руководства: Конверты сообщений Pub-Sub
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)