Отправить сообщение на несколько серверов pyzmq
Если у меня есть один клиент подключиться к нескольким серверам и попытаться отправить сообщение,
socket = context.socket(zmq.REQ)
socket.connect ("tcp://127.0.0.1:5565")
socket.connect ("tcp://127.0.0.1:5566")
socket.connect ("tcp://127.0.0.1:5567")
socket.send("Hello all")
только один сервер получит сообщение. В документации сказано, что pyzmq преобразует простую балансировку нагрузки на всех доступных серверах.
Есть ли способ отправить сообщение всем серверам, а не только одному?
Фон:
Я пытаюсь контролировать сеть малинового писа с моим компьютером. Мне нужно отправить сообщение всем им одновременно, но я не могу использовать модель PUB/SUB, потому что тогда им всем нужно ответить на это сообщение.
У меня есть один запросчик (главный компьютер), который отправляет запрос всем ответчикам (малиновый пис), и все они отвечают индивидуально. Например, я мог бы отправить одно сообщение с просьбой получить показания от датчика температуры, и я хочу, чтобы все малиновые писи прочитали датчик температуры и отправили его обратно.
3 ответа
Я просто использовал массив пар req/rep. Каждый клиент имеет несколько сокетов req, и каждый сервер имеет один сокет rep. Разве это не масштабируемое решение? Отправляемые данные не требуют высокой масштабируемости. Если это будет проблемой, я мог бы решить что-то с pub/sub.
Да.
Используйте соответствующий Формальный Шаблон Коммуникации.
Формализм ZMQ.REQ действительно ожидает, что компонент запрашивает какой-то другой процесс посредством отправки запроса, чтобы выполнить некоторую работу в ответ на сообщение. Таким образом, множественный выход нацелен на .connect()
построил транспортное отношение с, обслуживается в циклическом режиме, выбирая один за другим, в режиме честной очереди. Таким образом, компонент работает, но для другой цели, чем вы просите это сделать.
Решение
Попробуйте использовать более сложный шаблон формальной связи, который "распространяет" сообщение среди всех соответствующих партнеров (как PUB/SUB), но более сложные, более умные, отказоустойчивые производные схемы, которые бы отвечали потребностям вашего решения Raspberry PI.
Самая большая сила ZeroMQ заключается в том, что он снимает с вас низкоуровневые детали и дает вам огромные возможности в разработке всех необходимых распределенных масштабируемых формальных шаблонов формальной связи, которые вам нужны. Забудьте только о нескольких примитивах (строительных блоках), непосредственно перечисленных в привязке ZeroMQ. Подумайте о своей абстрактной схеме обработки сообщений / событий, а затем соберите элементы ZeroMQ, чтобы соответствовать этой схеме.
ZeroMQ [сокет] - это не шланг от А до Б. Это скорее порт доступа для диалогов с интеллектуальными узлами формальных коммуникационных шаблонов. Вы можете извлечь выгоду, что [сокет] может работать одновременно со многими классами транспорта... так что ваши формальные шаблоны связи могут охватывать сети L3 [TCP:]
+ войти в [IPC:]
а также [INPROC:]
каналы для обработки внутри [localhost].
Все работают параллельно (ну, конечно - почти параллельно, как только проверены в более мелких деталях)
Все работают в гладкой, интегрированной среде.
Откуда взять источник?
Лучший следующий шаг, который вы можете сделать для этого, - это IMHO, чтобы получить немного более глобальное представление, которое может показаться сложным для первых нескольких вещей, которые вы пытаетесь кодировать с помощью ZeroMQ, но если вы хотя бы перейдете на страницу 265 связанного кода, Том 1 [ asPdf ->], если бы не было пошагового чтения там.
Самая быстрая кривая обучения могла бы состоять в том, чтобы сначала иметь неэкспонированный вид на Рис.60 Публикация обновлений и Рис. 62 HA Clone Server для возможного подхода высокой доступности, а затем вернуться к корням, элементам и деталям.,
Используйте PUB/SUB для отправки запроса и совершенно отдельный сокет PUSH/PULL для получения ответов. Ответное сообщение, вероятно, должно содержать поле, в котором указано, из какого Pi оно пришло.
Альтернативный способ использует PUSH/PULL
вместо PUB/SUB
потому что с PUB/SUB
метод ваше сообщение может быть потеряно, если подписчик не был выполнен, но в PUSH/PULL
метод, когда клиент / отправитель публикует сообщение (PUSH
), сервер / получатель может получить его в любое время с помощью PULL
приписывать.
Вот простой пример:
Фрагмент кода на стороне клиента:
import zmq
def create_push_socket(ip, port):
print('PUB')
context = zmq.Context()
socket = context.socket(zmq.PUSH)
zmq_address = "tcp://{}:{}".format(ip, port)
socket.connect(zmq_address)
return socket
sock1 = create_push_socket('RPi-1-IP', RPi-1-PORT)
sock2 = create_push_socket('RPi-1-IP', RPi-1-PORT)
sock3 = create_push_socket('RPi-1-IP', RPi-1-PORT)
sock1.send('Hello')
sock2.send('Hello')
sock3.send('Hello')
Фрагмент кода на стороне сервера:
import zmq
def listen():
context = zmq.Context()
zmq_ = context.socket(zmq.PULL)
zmq_.bind('tcp://*:6667')
print(zmq_.recv())
listen()