Client / Server¶
Request/Reply pattern
Most basic pattern is client/server model, where client sends a request and server replies to the request.
There is one difference from zmq.PAIR and other type of ZMQ sockets.
- ZMQ REQ sockets can connect to many servers.
- The requests will be interleaved or distributed to both the servers.
With socket zmq.PAIR, you could send any number of messages among connected peers or client/server.
- socket zmq.REQ will block on send unless it has successfully received a reply back.
- socket zmq.REP will block on recv unless it has received a request.
Each Request/Reply is paired and has to be successful.
reqrep_server.py
Provide port as command line argument to run server at two different ports.
import zmq
import time
import sys
port = "5556"
if len(sys.argv) > 1:
port = sys.argv[1]
int(port)
Server is created with a socket type “zmq.REP” and is bound to well known port.
context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind("tcp://*:%s" % port)
It will block on recv() to get a request before it can send a reply.
socket.bind("tcp://*:%s" % port)
while True:
# Wait for next request from client
message = socket.recv()
print "Received request: ", message
time.sleep (1)
socket.send("World from %s" % port)
reqrep_client.py
Provide two ports of two different servers to connect to simultaneously.
import zmq
import sys
port = "5556"
if len(sys.argv) > 1:
port = sys.argv[1]
int(port)
if len(sys.argv) > 2:
port1 = sys.argv[2]
int(port1)
Client is created with a socket type “zmq.REQ”. You should notice that the same socket can connect to two different servers.
context = zmq.Context()
print "Connecting to server..."
socket = context.socket(zmq.REQ)
socket.connect ("tcp://localhost:%s" % port)
if len(sys.argv) > 2:
socket.connect ("tcp://localhost:%s" % port1)
You have to send a request and then wait for reply.
# Do 10 requests, waiting each time for a response
for request in range (1,10):
print "Sending request ", request,"..."
socket.send ("Hello")
# Get the reply.
message = socket.recv()
print "Received reply ", request, "[", message, "]"
Executing the scripts:
python reqrep_server.py 5546
python reqrep_server.py 5556
python reqrep_client.py 5546 5556
Output:
Connecting to hello world server...
Sending request 1 ...
Received reply 1 [ World from 5556 ]
Sending request 2 ...
Received reply 2 [ World from 5546 ]
Sending request 3 ...
Received reply 3 [ World from 5556 ]
Sending request 4 ...
Received reply 4 [ World from 5546 ]
Sending request 5 ...
Received reply 5 [ World from 5556 ]
Sending request 6 ...
Any attempt to send another message to the socket (zmq.REQ/zmq.REP), without having received a reply/request will result in an error:
....
socket.send ("Hello")
socket.send ("Hello1")
....
Error: zmq.core.error.ZMQError: Operation cannot be accomplished in current state
Note
If you kill the server (Ctrl-C) and restart it, the client won’t recover properly.