ZMQ DEALER - ROUTER Communication

后端 未结 2 1158
萌比男神i
萌比男神i 2020-12-09 23:39

I am currently working on a project that requires some communication over the network of a different data types from some entities of a distributed system and I am using ZMQ

2条回答
  •  执笔经年
    2020-12-10 00:25

    You could have all clients send a "I am here" message at start-up. The central server could then store all the IDs, c.f. the initial communication between worker and router in here: http://zguide.zeromq.org/page:all#A-Load-Balancing-Message-Broker. The server would send out any received message to all currently known clients. You should add some heart beating in order to detect disconnected clients, c.f. http://zguide.zeromq.org/page:all#Heartbeating.

    However, ZeroMQ already comes with such a communication pattern: PUBSUB. In essence every client would have a DEALER and a SUB socket connected to the servers ROUTER and PUB sockets. The server simply sends out any received message via the PUB socket to all clients. If this would be a problem for the originating client, you can include the client ID in the message so that each client can filter out messages with their own ID. See also this example from the guide http://zguide.zeromq.org/page:all#Getting-an-Out-of-Band-Snapshot

    Another interesting pattern would be Republishing Updates from Clients:

    Here PUSH--PULL is used to send the updates to the server. This makes sense if there is no need for a reply message from the server. If you do not need the state request from that example, you can leave out the ROUTER--DEALER part. Here a sample implementation using Python for brevity. The server listens to the PULL socket and sends out everything via the PUB socket:

    import zmq
    
    def main():
        # context and sockets
        ctx = zmq.Context()
        publisher = ctx.socket(zmq.PUB)
        publisher.bind("tcp://*:5557")
        collector = ctx.socket(zmq.PULL)
        collector.bind("tcp://*:5558")
    
        while True:
            message = collector.recv()
            print "I: publishing update %s" % message
            publisher.send(message)
    
    if __name__ == '__main__':
        main()
    

    The client listens to the PUB socket for some time. If a message is received it is logged. If the timeout is reached, a message is generated with a 1 in 10 chance:

    import random
    import time
    
    import zmq
    
    def main():
    
        # Prepare our context and subscriber
        ctx = zmq.Context()
        subscriber = ctx.socket(zmq.SUB)
        subscriber.setsockopt(zmq.SUBSCRIBE, '')
        subscriber.connect("tcp://localhost:5557")
        publisher = ctx.socket(zmq.PUSH)
        publisher.connect("tcp://localhost:5558")
    
        random.seed(time.time())
        while True:
            if subscriber.poll(100) & zmq.POLLIN:
                message = subscriber.recv()
                print "I: received message %s" % message
            else:
                rand = random.randint(1, 100)
                if rand < 10:
                    publisher.send("%d" % rand)
                    print "I: sending message %d" % rand
    
    if __name__ == '__main__':
        main()
    

提交回复
热议问题