首页 > 解决方案 > Ruby 和 Python 之间的 ZeroMQ PAIR/PAIR 连接

问题描述

我想使用 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

顺便说一句:我正在使用 Python 3.6.9 和 Ruby 2.6.5

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

标签: pythonrubyzeromq

解决方案


欢迎来到零之禅!
如果您从未使用过 ZeroMQ,
您可以在这里先看看“ ZeroMQ原则在不到五秒的时间内”,然后再深入了解更多细节

在我连接客户端之前,它不显示任何内容。

当然,它不会,您的代码强制要求阻止,直到PAIR/PAIR传递通道恰好能够传递消息。正如 v4.2+ API 定义的那样, - 方法将在“静音状态.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 )

最后但并非最不重要的 :

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

正如 API 文档所解释的:

ZMQ_PAIR套接字是为跨zmq_inproc(7) 传输的线程间通信而设计的,并且实现诸如自动重新连接之类的功能。

没有最好的方法来做到这一点,因为 Python / Ruby 不是线程间通信的情况。ZeroMQ 自 v2.1+ 以来已明确警告说,PAIR/PAIR原型是实验性的,应该仅在牢记这一点的情况下使用。

人们总是可以用一串 -simplex 通道替换每个这样的用例PUSH/PULL,从而为一对 a .send()-only + -only 通道提供相同的舒适度.recv()


推荐阅读