проблема при реализации неблокирующего механизма публикации с zeromq

#python #nonblocking #zeromq

#python #неблокирующий #zeromq

Вопрос:

Я хотел бы связать два процесса (отправителя и получателя) с использованием zeromq. Теперь, если процесс получателя не запущен, я бы хотел, чтобы процесс отправителя продолжил свое выполнение, даже если сообщение потеряно.

Пытаясь реализовать его с использованием шаблона PUB-SUB, я заметил, что если получатель не запущен, отправитель вешает трубку. Например, в следующем исходном коде отправителя:

 import zmq

context = zmq.Context()
sender = context.socket(zmq.PUB)
sender.connect("tcp://localhost:5555")

sender.send("Sending to nobody", NOBLOCK)

print "Msg sent"
  

когда получатель не работает, сообщение «Отправлено сообщение» никогда не печатается, а отправитель остается в «sender.send («Отправка никому», NOBLOCK)» навсегда. Кроме того, я попытался проверить, работает ли приемник или не получает возврат функции connect, но в обоих случаях всегда «Нет».

Я использую Python 2.6.5 и zeromq 2.1

Кто-нибудь знает, что это происходит, или альтернативное решение? (Я пробовал использовать PULL-PUSH и REQ-REP, но аналогичные результаты)

Заранее большое спасибо

Комментарии:

1. Этот код фактически не выполняется (символ NOBLOCK не определен). Это действительно помогает публиковать код, который люди могут вырезать и вставлять.

Ответ №1:

После исправления вашего примера:

 import zmq

context = zmq.Context()
sender = context.socket(zmq.PUB)
sender.connect("tcp://localhost:5555")

sender.send("Sending to nobody", zmq.NOBLOCK)

print "Msg sent"
  

Поведение, которое я вижу, заключается в том, что фраза «Сообщение отправлено» печатается, но после этого скрипт зависает и фактически никогда не завершается. Проблема здесь в том, что он зависает при close() системном вызове.

Вы можете изменить это поведение, установив LINGER параметр в своем сокете:

 sender = context.socket(zmq.PUB)
sender.setsockopt(zmq.LINGER, 100)
  

Это значение здесь представляет собой время задержки в миллисекундах. Смотрите страницу руководства для zmq_setsockopt получения дополнительной информации. Практический эффект этого заключается в том, что ZMQ будет ждать только задерживаться на миллисекунды перед закрытием сокета.

Не устанавливайте это значение слишком низким, потому что это приведет к потере сообщений, даже если отправитель прослушивает (потому что ZMQ может закрыть сокет до того, как сообщение действительно будет доставлено).

Комментарии:

1. Почему sender.close() и context.term() не возвращают код ошибки при отключении приемника и zmq. ЗАДЕРЖИТЕСЬ, это 100 или больше? Или как я могу теперь узнать, что отправка сообщения не удалась?

Ответ №2:

Вы можете легко изменить: sender.connect("tcp://localhost:5555") на sender.bind("tcp://localhost:5555") и наоборот на receiver.

Это дает вам возможность подключать приемник везде, где вам нравится. Отправитель будет работать независимо от того, есть получатели или нет.