5

我通过使用 ZeroMQ 的路由器实现了一个简单的请求-回复架构。这适用于PyZMQ 版本 2.1.11。不幸的是,当我在PyZMQ 版本 14.0.0上测试它时,发送方(REQ)可以发送到路由器,然后路由器收到它的消息并发送到接收方(REP),但接收方没有收到消息!当我将 PyZMQ 从 2.1.11 升级到 14.0.0 时,我遇到了这个问题。

请求 <-> 路由器 <-> 代表

这是我的代码:

发件人.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)

路由器.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))

接收器.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))

当我使用这种架构时:

routing with DEALER

The DEALER does not route to multiple receivers. DEALER only use round-robin method for sending messages to receivers. If ROUTER could be used instead of DEALER, then messages could be routed to specific receivers and will do round-robin between those.

4

2 回答 2

3

A ROUTER to REP socket is an invalid combination as explained here: http://zguide.zeromq.org/page:all#Request-Reply-Combinations

于 2013-11-12T21:19:19.927 回答
3

According to what @nos said, ROUTER to REP is invalid combination but the ROUTER to ROUTER socket is valid one. Simply, I changed the REP socket to ROUTER! Revised code is here:

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))
于 2013-11-16T10:11:43.797 回答