Соединение ZeroMQ PAIR / PAIR между Ruby и Python - PullRequest
1 голос
/ 10 января 2020

Я хочу установить простое соединение между программой Python и Ruby, использующей ZeroMQ, я пытаюсь использовать соединение PAIR, но не смог.

Это мой код в python (сервер):

import zmq 
import time 

port = "5553" 
context = zmq.Context() 
socket = context.socket(zmq.PAIR) 
socket.bind("tcp://*:%s" % port) 

while True: 
    socket.send(b"Server message to client3") 
    print("Enviado mensaje") 
    time.sleep(1)

Ничего не отображается, пока я не подключу клиента.

Это код в Ruby (клиент)

require 'ffi-rzmq'
context = ZMQ::Context.new
subscriber = context.socket ZMQ::PAIR
subscriber.connect "tcp://localhost:5553"
loop do
    address = ''
    subscriber.recv_string address
    puts "[#{address}]"
end

Сценарий ruby просто зависает, ничего не печатается, а сценарий python начинает печатать Enviando mensaje

Кстати: я использую Python 3.6.9 и Ruby 2.6.5

Как правильно подключить zmq PAIR между Ruby и Python?

1 Ответ

1 голос
/ 10 января 2020

Добро пожаловать в Zen of Zero!
В случае, если кто-то никогда не работал с ZeroMQ,
здесь можно сначала посмотреть " ZeroMQ Принципы меньше чем Пять секунд ", прежде чем углубляться в дальнейшие детали

Q : Ничего не отображается, пока я не подключу client.

Конечно, это не так, ваш код настоятельно предлагается заблокировать до тех пор, пока канал доставки PAIR/PAIR не сможет доставить сообщение. Как определяет API v4.2 +, метод .send() будет блокироваться в течение всего периода " состояния отключения звука ".

Когда гнездо ZMQ_PAIR переходит в состояние отключения звука из-за того, что достигнут максимальный уровень воды для подключенного узла, или если узел не подключен, тогда любой zmq_send ( 3) операции с сокетом должны блокироваться, пока одноранговый узел не станет доступным для отправки; сообщения не отбрасываются.

Может попробовать неблокирующий режим отправки (всегда признак хорошей инженерной практики, позволяющей избежать блокировки, тем более в ) и лучше включить также <aSocket>.close() и <aContext>.term() в качестве практического правила (лучше всего при явном .setsockopt( zmq.LINGER, 0 )) для избежания зависаний и в качестве хорошей инженерной практики для явного закрытия ресурсов и их освобождения обратно к системе

socket.send( b"Server message #[_{0:_>10d}_] to client3".format( i ), zmq.NOBLOCK )

Последнее, но не менее важное:

Q : Как правильно подключить zmq PAIR между Ruby и Python?

, как объясняется в документации API:

ZMQ_PAIR сокеты предназначены для межпотоковой связи через транспорт zmq_inproc (7) и выполняют , а не реализуют такие функции, как автоматическое переподключение.

лучше не бывает способ сделать это, так как Python / Ruby не случай межпотоковой связи. ZeroMQ начиная с v2.1 + явно предупреждал, что архетип PAIR/PAIR является экспериментальным и должен использоваться только с учетом этого.

Можно всегда заменяйте каждый такой сценарий использования тандемом PUSH/PULL -симплексных каналов, обеспечивая одинаковый комфорт с парой .send() -только + .recv() -только каналов.

...