我正在尝试创建一个收集发送数据的系统 我有两个小脚本,一个应该接收数据的receiver.py,以及应该发送它的发送者,我尝试使用1-1连接的那一刻,但最后我需要多个发送器和一个接收器来处理传入数据。我尝试使用0mq发布者/订阅者模式来完成此任务。
#receiver.py
def receive():
context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.setsockopt(zmq.SUBSCRIBE, 'Child:')
socket.bind('tcp://localhost:5000')
while True:
print 'Parent received: %s' % socket.recv()
receive()
#sender.py
def send(data):
context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.connect('tcp://localhost:5000')
socket.send('Sender: %i' % data)
socket.close()
print "sent"
send(10)
当我启动receiver.py时它只是等待数据,当我运行sender.py时没有收到任何内容。我很感激建议,实际上我甚至不确定发布者/订阅者是否是我的场景的最佳模式(多个传感器通过本地网络将数据发送到一台服务器进行实时处理)。
答案 0 :(得分:2)
为了理解发生了什么,我改写了它:
import zmq
import threading
import time
def receive():
context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.bind("tcp://127.0.0.1:5000")
socket.setsockopt(zmq.SUBSCRIBE, '')
while True:
print 'Parent received: %s' % socket.recv()
threading.Thread(target=receive).start()
def send(data):
context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.connect("tcp://localhost:5000")
while data:
socket.send('Sender: %i' % data)
data -= 1
time.sleep(1)
输出:
>>> send(10)
Parent received: Sender: 9
Parent received: Sender: 8
Parent received: Sender: 7
Parent received: Sender: 6
Parent received: Sender: 5
Parent received: Sender: 4
Parent received: Sender: 3
Parent received: Sender: 2
Parent received: Sender: 1
关键点是:
127.0.0.1
来绑定您的localhost Child:
或将其更改为Sender:
或在{{1}中更改send()
Sender:
(我已经选择了第一个)Child:
,例如以下示例,但您不会丢失任何消息。
send()
输出:
def send(data):
context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.connect("tcp://localhost:5000")
while data:
time.sleep(1)
socket.send('Sender: %i' % data)
data -= 1
socket.close()
答案 1 :(得分:1)
如果您无法让示例正常运行,则表明您的ZMQ库安装有问题,或者您的库版本与您的库版本不兼容,这是一个好兆头。绑定你的使用。在那里开始检查,并始终首先尝试逐字运行示例,以确保所有内容至少与参考代码一起使用。
但是,我确实看到您的代码中至少有一个问题会导致您永远不会收到消息。
在您的订阅者中,您订阅了“孩子:'”,但在您的发布商中,您永远不会发送与之匹配的消息。 "正确"这样做的方法是发送一个多帧消息,但为了简化代码,您还可以发送一个以您的主题开头的字符串,如下所示:
socket.send('Child: Sender: %i' % data)
或者,您可以更改订阅者以适合当前的消息模式:
socket.setsockopt(zmq.SUBSCRIBE, 'Sender:')
最后但并非最不重要的是,如果您想订阅发布商可能发送的所有内容,您可以订阅空字符串:
socket.setsockopt(zmq.SUBSCRIBE, '')
......这最后一个可能对你的情况是正确的。因此,结果代码如下:
#receiver.py
def receive():
context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.setsockopt(zmq.SUBSCRIBE, '')
socket.bind('tcp://localhost:5000')
while True:
print 'Parent received: %s' % socket.recv()
receive()
#sender.py
def send(data):
context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.connect('tcp://localhost:5000')
socket.send('Sender: %i' % data)
socket.close()
print "sent"
send(10)
解决分点,问题和评论:
bind()
的订阅者和connect()
的发布者更合适(因为您已经完成),ZMQ并不关心您仅基于套接字类型使用。您的订阅者是您的服务器",您的发布商是您的客户",因此SUB应bind()
,PUB应为connect()
。