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
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: PUB
—SUB
. 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()