Объединение pub/sub с req/rep в zeromq

Как клиент может подписаться и послушать ответы с помощью zeromq? То есть, на стороне клиента я хотел бы запустить цикл, который получает только сообщения и выборочно отправляет запросы, а на стороне сервера я бы хотел опубликовать большую часть времени, но иногда также получать запросы. Похоже, мне придется иметь два разных сокета - по одному для каждого режима общения. Можно ли избежать этого и на стороне сервера получать "уведомления о запросах" из сокета в потоке обратного вызова zeromq, пока нажимаете сообщения на сокет в моем собственном потоке?

Ответ 1

Я ужасно новичок в ZeroMQ, поэтому я не уверен, что то, что вы хотите, считается наилучшей практикой или нет. Однако решение, использующее несколько сокетов, довольно просто, используя zmq_poll.

Основная идея заключалась бы в том, чтобы иметь как клиент, так и сервер:

  • открыть сокет для pub/sub
  • открыть сокет для req/rep
  • мультиплекс посылает и принимает между двумя сокетами в цикле с помощью zmq_poll в бесконечном цикле
  • обрабатывать req/rep и pub/sub события в цикле по мере их возникновения

Использование zmq_poll таким образом с несколькими сокетами хорошо, потому что оно полностью избегает потоков. В руководстве 0MQ есть хороший пример здесь. Обратите внимание, что в этом примере они используют тайм-аут -1 в zmq_poll, что заставляет его блокировать до тех пор, пока по крайней мере одно событие не произойдет в любом из мультиплексированных сокетов, но довольно часто используется тайм-аут x миллисекунд или что-то еще если вашему циклу необходимо выполнить и другую работу.

Ответ 2

Вы можете использовать 2 потока для обработки разных сокетов. Проблема в том, что если вам нужно обмениваться данными между потоками, вам необходимо синхронизировать их безопасным способом.

Альтернативой является использование ZeroMQ Poller для выбора сокетов, на которых есть новые данные. Затем процесс будет использовать один цикл в способе, описанном bjlaub.

Ответ 3

Это может быть выполнено с использованием вариации/подмножества протокола Majordomo. Здесь идея:

Ваш сервер будет роутером, а ваши клиенты будут дилерскими сокетами. При подключении к серверу клиент должен отправить какую-либо подписку или сообщение "привет" (вашего дизайна). Сервер получает этот пакет, но (будучи роутер-сокет) также получает идентификатор этого клиента. Когда серверу необходимо отправить что-то этому клиенту (через ваш проект), он отправляет его этому идентификатору. Клиент может отправлять и получать по желанию, так как это дилерский сокет.