Я хотел бы сообщить два процесса (отправитель и получатель) с помощью 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"
когда приемник не работает, сообщение "Msg sent" никогда не печатается, и отправитель остается на "sender.send(" Отсылка никому ", NOBLOCK)" навсегда. Кроме того, я попытался проверить, встал ли приемник или не получил возврат функции соединения, но в обоих случаях он всегда "Нет".
Я использую Python 2.6.5 и zeromq 2.1
Кто-нибудь знает, что это значит, или альтернативное решение? (Я пытался использовать PULL-PUSH и REQ-REP, но аналогичные результаты)
Большое спасибо заранее
После фиксации вашего образца:
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"
Поведение, которое я вижу, это то, что фраза "Msg sent" напечатана, но скрипт зависает после этого и никогда не завершается. Проблема здесь в том, что она висит на системном вызове close()
.
Вы можете изменить это поведение, установив опцию LINGER
в гнездо:
sender = context.socket(zmq.PUB)
sender.setsockopt(zmq.LINGER, 100)
Это значение здесь - время задержки в миллисекундах. Для zmq_setsockopt
дополнительной информации см. zmq_setsockopt
страницу zmq_setsockopt
. Практическое влияние этого заключается в том, что ZMQ будет ждать только миллисекунды до закрытия сокета.
Не устанавливайте это значение слишком низко, потому что это приведет к потере сообщений, даже если отправитель прослушивает (поскольку ZMQ может закрыть сокет до того, как сообщение действительно было доставлено).
Вы можете легко изменение: sender.connect("tcp://localhost:5555")
на sender.bind("tcp://localhost:5555")
и наоборот - на приемнике.
Это дает вам возможность подключать приемник там, где вам нравится. Отправитель будет работать независимо от того, есть ли приемники или нет.