zeromq同时订阅和发布

问题描述 投票:3回答:2

我正在尝试在python的debian / multiprocess情况下使用zeromq。我有几个过程可以解码来自多个传感器的原始数据,并在zmq中发布。到目前为止,一切都很好。我有一个计算过程,该过程在zmq上订阅原始数据,并执行一些计算。然后,它需要发布其答案以供其他进程记录和使用。因此,我的计算过程需要在同一过程中进行订阅和发布。

import zmq
import json
context = zmq.Context()

sub = context.socket(zmq.SUB)
sub.setsockopt(zmq.SUBSCRIBE, '')
sub.setsockopt(zmq.RCVBUF, 0)
sub.bind("tcp://127.0.0.1:5000")

pub = context.socket(zmq.PUB)
pub.bind("tcp://127.0.0.1:5000")

我尝试了上面的方法,但是没有运气。它返回一个错误...

File "socket.pyx", line 465, in zmq.core.socket.Socket.bind (zmq/core/socket.c:4749)
zmq.core.error.ZMQError: Address already in use

我阅读了文档,谷歌等,但现在完全卡住了。

python linux zeromq publish-subscribe
2个回答
2
投票

您尝试两次绑定到同一端口(5000),这会导致Address already in use错误-您只能将一个套接字绑定到端口。

但是sub套接字不应该bind(),它应该对另一个进程正在发布到的某个主机/端口执行connect()(即完成bind()的操作)。该代码应类似于:

sub = context.socket(zmq.SUB)
sub.setsockopt(zmq.SUBSCRIBE, '')
sub.setsockopt(zmq.RCVBUF, 0)
sub.connect("tcp://127.0.0.1:XXXX")

pub = context.socket(zmq.PUB)
pub.bind("tcp://127.0.0.1:YYYY")

我猜您不是要使端口XXXXYYYY相同,然后相同的进程将监听它自己发布的消息。


0
投票

首先,您只能绑定到一个套接字一次。如果尝试绑定到已经绑定的套接字,则会收到您看到的错误。

第二,在您提供的示例中,sub应该进行绑定,而pub应该进行连接。

我对johlo的答案以及与此相关的一些评论有疑问。声称订户不应绑定到套接字。这是BAD建议!

一般的经验法则是,[[预期寿命更长的过程应该进行绑定,其他应该连接。注意,这是一般规则,而不是法律。以我的经验,订户的寿命通常更长。

以下是要考虑的一些情况:

如果您控制该应用程序,请问自己:“如果没有人在听,我是否应该发布需要捕获的重要数据?”如果答案为“否”,请首先启动订户并将其绑定到套接字。然后,发布者进行连接...如果有多个订阅者,并且您处于控制之中,则由您确定哪个寿命最长。

在许多发布/订阅方案中,发布者和订阅者都不知道彼此的存在。

如果您不受该应用程序的控制,而您正在创建发布者,则可以放心地假设也许在某个时候(现在|以后)某人将订阅您的消息。只需让您的发布者连接到套接字即可。如果没有人绑定到套接字,没什么大不了的,无论如何也没有人在听。

类似于上面的示例,如果您不受控制并且正在创建订户,则不能安全地假定您是唯一的订户。也许您尝试绑定到套接字。如果引发异常|错误,请捕获并进行连接。

另一方面,也许您有一个不断输出数据的发布者,并且它像传感器之类的东西一样一直处于打开状态,也许您有一些订阅者会在需要时来来去去。在这种情况下,您的发布者显然会进行绑定,而和订阅者会进行连接。

如您所见,只要您知道套接字只能绑定一次,就可以选择绑定的方式。

© www.soinside.com 2019 - 2024. All rights reserved.