#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.
Это дает вам возможность подключать приемник везде, где вам нравится. Отправитель будет работать независимо от того, есть получатели или нет.