5

ZeroMQ を使用したルーターを使用して、単純な要求と応答のアーキテクチャを実装しました。これは、PyZMQ バージョン 2.1.11で正しく機能します。残念ながら、PyZMQ バージョン 14.0.0でテストすると、送信者 (REQ) はルーターに送信でき、ルーターはメッセージを受信して​​受信者 (REP) に送信できますが、受信者はメッセージを受信しません! PyZMQ をバージョン 2.1.11 から 14.0.0 にアップグレードしたときに、この問題に遭遇しました。

REQ <-> ROUTER <-> REP

これが私のコードです:

送信者.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))

受信機.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、メッセージは特定の受信者にルーティングされ、それらの間でラウンドロビンが実行されます。

4

2 に答える 2

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