Ruby 和 Python 之间的 ZeroMQ PAIR/PAIR 连接

ZeroMQ PAIR/PAIR connection between Ruby an Python

我想使用 ZeroMQ 在 Python 程序和 Ruby 程序之间建立一个简单的连接,我正在尝试使用 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

B.T.W:我正在使用 Python 3.6.9 和 Ruby 2.6.5

在 Ruby 和 Python 之间连接 zmq PAIR 的正确方法是什么?

欢迎来到零之禅!
如果一个人从未使用过 ZeroMQ,
在深入了解更多细节之前,您可能会喜欢先看一下“

Q : It does not display anything until I connect a client.

当然,它不会,您的代码强制要求阻塞,直到 PAIR/PAIR 传递通道碰巧能够传递消息。正如 v4.2+ API 定义的那样,.send()-方法将在“静音状态".

When a ZMQ_PAIR socket enters the mute state due to having reached the high water mark for the connected peer, or if no peer is connected, then any zmq_send(3) operations on the socket shall block until the peer becomes available for sending; messages are not discarded.

可以尝试非阻塞发送模式(总是避免阻塞的良好工程实践的标志,在 中越多越好)并且最好还包含 <aSocket>.close()<aContext>.term() 作为避免挂断的经验法则(最好使用明确的 .setsockopt( zmq.LINGER, 0 ) )并且作为一种良好的工程实践来显式关闭资源并将它们释放回系统

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

最后但并非最不重要的一点:

Q : What is the correct way to connect a zmq PAIR between Ruby and Python?

如 API 文档所述:

ZMQ_PAIR sockets are designed for inter-thread communication across the zmq_inproc(7) transport and do not implement functionality such as auto-reconnection.

没有最好的方法来做到这一点,因为 Python / Ruby 不是线程间通信的情况。 ZeroMQ 自 v2.1+ 以来明确警告,PAIR/PAIR 原型是一个 experimental 并且应该只与轴承一起使用介意。

人们总是可以用 PUSH/PULL-单工通道的串联替换每个这样的用例,用一对 .send()-仅+ .recv()-仅频道。