我使用ZeroMQ实现了一个简单的请求 - 回复架构和路由器。这适用于 PyZMQ版本2.1.11 。不幸的是,当我在 PyZMQ版本14.0.0 上测试它时,发送方(REQ)可以发送到路由器然后路由器收到它的消息并发送到接收方(REP)但接收方没有收到消息! 当我将PyZMQ从2.1.11升级到14.0.0时,我遇到了这个问题。
REQ< - > ROUTER< - > REP
这是我的代码:
sender.py
import zmq
import time
if __name__=='__main__':
context = zmq.Context()
socket = context.socket(zmq.REQ)
socket.setsockopt(zmq.IDENTITY, "S")
socket.connect("tcp://127.0.0.1:6660")
i = 0
while True:
i += 1
socket.send("R", zmq.SNDMORE)
socket.send("", zmq.SNDMORE)
socket.send("Message: %d" % i)
print("Message : %d sent" % i)
fromAddr = socket.recv()
empty = socket.recv()
resp = socket.recv()
print("%s received!" % str(resp))
time.sleep(1)
router.py
import zmq
import time
if __name__=='__main__':
context = zmq.Context()
frontend = context.socket(zmq.ROUTER)
frontend.bind("tcp://*:6660")
poll = zmq.Poller()
poll.register(frontend, zmq.POLLIN)
while True:
sockets = dict(poll.poll(100))
if frontend in sockets:
if sockets[frontend] == zmq.POLLIN:
fromAddr = frontend.recv()
empty = frontend.recv()
toAddr = frontend.recv()
empty = frontend.recv()
msg = frontend.recv()
print("Message received from %s must be send to %s [%s]" % (str$
frontend.send(toAddr, zmq.SNDMORE)
frontend.send("", zmq.SNDMORE)
frontend.send(fromAddr, zmq.SNDMORE)
frontend.send("", zmq.SNDMORE)
frontend.send(msg)
print("Message has been send to %s!" % str(toAddr))
receiver.py
import zmq
import time
if __name__=='__main__':
context = zmq.Context()
socket = context.socket(zmq.REP)
socket.setsockopt(zmq.IDENTITY, "R")
socket.connect("tcp://127.0.0.1:6660")
while True:
print("Wating for request...")
toAddr = socket.recv()
empty = socket.recv()
req = socket.recv()
print("%s received!" % str(req))
socket.send(toAddr, zmq.SNDMORE)
socket.send(empty, zmq.SNDMORE)
socket.send("Reply to %s" % str(req))
当我使用这种架构时:
DEALER
不会路由到多个接收者。 DEALER
仅使用循环方法向接收方发送消息。如果可以使用ROUTER
代替DEALER
,则可以将消息路由到特定的接收者,并在这些消息之间进行循环。
答案 0 :(得分:3)
ROUTER to REP socket是一个无效的组合,如下所述:http://zguide.zeromq.org/page:all#Request-Reply-Combinations
答案 1 :(得分:3)
根据@nos所说的,ROUTER到REP是无效组合,但ROUTER到ROUTER套接字是有效的。简单地说,我将REP套接字更改为ROUTER!修改后的代码在这里:
import zmq
if __name__=='__main__':
context = zmq.Context()
socket = context.socket(zmq.ROUTER) # Changed
socket.setsockopt(zmq.IDENTITY, "R1")
socket.connect("tcp://127.0.0.1:6660")
while True:
print("Wating for request...")
me = socket.recv() # New
empty = socket.recv() # New
toAddr = socket.recv()
empty = socket.recv()
req = socket.recv()
print("%s received!" % str(req))
socket.send(me, zmq.SNDMORE) # New
socket.send(empty, zmq.SNDMORE) # New
socket.send(toAddr, zmq.SNDMORE)
socket.send(empty, zmq.SNDMORE)
socket.send("Reply to %s" % str(req))