我在ZMQ中设置了一个REP/DEALER连接,发现当REP向DEALER发送一个msg时,后者必须重新两次才能获得该消息.为什么是这样?
复制它的代码是来自此SO答案的代码的修改版本.他们的代码每个工人只收到一次,但我测试了这个,我只回到了一个"世界".我不得不接受四次以获得2个"世界",因此:
import zmq
import time
import sys
import threading
SOCKET_NAME = "tcp://127.0.0.1:8000"
#SOCKET_NAME = "inproc://mysocket"
def dealerRoutine(context):
socket = context.socket(zmq.DEALER)
socket.bind(SOCKET_NAME)
time.sleep(1)
socket.send("", zmq.SNDMORE)
socket.send("hello")
socket.send("", zmq.SNDMORE)
socket.send("hello")
print "first msg", socket.recv()
print "second msg", socket.recv()
print "third msg", socket.recv()
print "fourth msg", socket.recv()
socket.close()
def workerRoutine(context):
socket = context.socket(zmq.REP)
socket.connect(SOCKET_NAME)
s = socket.recv()
print "worker received", s
socket.send("world")
context = zmq.Context()
workers = []
for i in range(0, 2):
worker = threading.Thread(target=workerRoutine, args=([context]))
workers.append(worker)
worker.start()
dealerRoutine(context)
for worker in workers:
worker.terminated = True
context.term()
Run Code Online (Sandbox Code Playgroud)
我是RTFM,答案是:来自REP套接字的ZMQ消息包含在信封中.因此,在引擎盖下,REP需要一个带分隔符的消息,然后是消息内容; 然后,它剥离分隔符并仅将内容返回给应用程序.这就是DEALER发送这样的消息的原因:
socket.send("", zmq.SNDMORE)
socket.send("hello")
Run Code Online (Sandbox Code Playgroud)
,因为REP希望在那里分隔它将剥离,并且DEALER不会自动为我们做.
现在,当REP将消息发送回DEALER时,反之亦然.在应用程序中,看起来我们只是在没有任何额外的情况下发送数据:
socket.send("world")
Run Code Online (Sandbox Code Playgroud)
但是,REP套接字在前面添加一个分隔符,以便消息"收到信封"发送.
那么,为什么经销商需要接收两次?
因为,与REP不同,DEALER不会隐式处理分隔符.它保持一切正常.因此,既然我们知道它是从REP套接字接收的,我们可以安全地接收两次,一个用于删除自己的分隔符,另一个用于实际获取数据:
socket.recv() # discard delimiter
our_data = socket.recv()
Run Code Online (Sandbox Code Playgroud)
来源:
归档时间: |
|
查看次数: |
3060 次 |
最近记录: |