我已经设置了两个小脚本,用pyzmq模仿发布和订阅过程。但是,我无法使用inproc
传输将消息发送到我的订阅者客户端。我可以使用tcp://127.0.0.1:8080
罚款,而不是inproc。
pub_server.py
import zmq
import random
import sys
import time
context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.bind("inproc://stream")
while True:
socket.send_string("Hello")
time.sleep(1)
sub_client.py
import sys
import zmq
# Socket to talk to server
context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.setsockopt_string(zmq.SUBSCRIBE, '')
socket.connect("inproc://stream")
for x in range (5):
string = socket.recv()
print(string)
如何成功更改代码,以便能够在两个脚本之间使用inproc传输方法?
修改
我已更新我的代码以进一步反映@larsks评论。我仍然没有收到我发布的字符串 - 我做错了什么?
import threading
import zmq
def pub():
context = zmq.Context()
sender = context.socket(zmq.PUB)
sender.connect("inproc://hello")
lock = threading.RLock()
with lock:
sender.send(b"")
def sub():
context = zmq.Context()
receiver = context.socket(zmq.SUB)
receiver.bind("inproc://hello")
pub()
# Wait for signal
string = receiver.recv()
print(string)
print("Test successful!")
receiver.close()
if __name__ == "__main__":
sub()
答案 0 :(得分:1)
顾名思义,inproc
套接字只能在同一进程中使用 。如果你要重写你的客户端和服务器,以便在同一个进程中有两个线程可以使用inproc
,但是这个套接字类型根本不适合你正在做的事情。
documentation在这一点上非常明确:
进程内传输直接在共享单个ØMQ上下文的线程之间通过内存传递消息。
<强>更新强>
看一下更新的代码,首先突出的问题是,虽然上面引用的文档说“......在共享单个ØMQ上下文的线程之间”,但是您正在创建两个上下文在你的代码中。通常情况下,您只需在程序中调用zmq.Context()
一次。
接下来,您永远不会订阅您的订阅者,因此即使其他所有内容都正常工作,您也不会收到任何消息。
最后,您的代码将体验slow joiner problem:
有一个关于PUB-SUB套接字的重要事项:你不知道用户何时开始收到消息。即使您启动订阅者,等待一段时间,然后启动发布者,订阅者也将始终错过发布者发送的第一封邮件。这是因为当订阅者连接到发布者时(需要很少但非零的时间),发布者可能已经发送了消息。
发布/订阅模型不适用于单个消息,也不是可靠的传输。
所以,总结一下:
inproc
套接字,因此您需要将两个函数放在不同的线程中。 ZMQ文档中有example using PAIR
sockets可能提供一个有用的起点。 PAIR
套接字用于协调inproc
套接字上的线程,与pub / sub套接字不同,它们是双向的,不受“慢速连接”问题的影响。
答案 1 :(得分:0)
正如@larsks 之前提到的,上下文对象应该是相同的。全局声明上下文对象并在 pub 和 sub 函数中使用它,而不是为每个函数创建新的。