In the previous post I’ve outlined what to expect from ZeroMQ. In this is post I’ll focus on infrastructure and messaging patterns options ZeroMQ gives us to play with.
ZeroMQ gives us the choice of how to organize your “network”. In the simple case it’s a “server” who binds to a socket and a “client” who connects to the “server”. The “client” sends a message and the “server” receives it.
It’s possible to bind a socket to an address and at the same time to connect to other end point. This means that we can use it as a forwarder:
Those examples use pipeline messaging pattern and it’s to time to explain how to handle the message flow.
ZeroMQ supports four messaging patterns:
- Pipeline - used for distributing data to nodes arranged in a pipeline
- Request-Reply - used for sending requests from a client to one or more instances of a service, and receiving subsequent replies to each request sent
- Publish-Subscribe - used for sending requests from a client to one or more instances of a service, and receiving subsequent replies to each request sent
- Exclusive Pair - advanced pattern used for communicating exclusively between two peers
We can see the usage of pipeline pattern in the previous example. ZMQ::UPSTREAM(ZMQ::PULL) socket only gets data, ZMQ::DOWNSTREAM(ZMQ::PUSH) socket pushes date.
In more complicated manner, a pipeline stage can connect to multiple nodes. If so data is automatically load-balanced among all connected nodes.
NOTICE: ZMQ::DOWNSTREAM/ZMQ::UPSTREAM are deprecated. The new names of the socket types are ZMQ::PUSH/ZMQ::PULL. Right now the names are not updated in zmq ruby gem, but in ffi version everything is working correctly.
- create ZMQ::REQ socket and connect to server
- send a message using send method
- capture reply with recv method
Accepting request and sending reply
- create ZMQ::REP socket and bind on specific address/port
- receive message with recv method
- send a reply with send method
It’s also possible to make more than one request per socket. Just use connect on different addresses/ports.
In the following example we’re sending 10 numbers as 10 separate requests, the server get the request(the number), multiply it and then send it back to the client.
It’s the well know pattern. And this is how it works in ZeroMQ
- Create a ZMQ::PUB socket and bind it on address/port
- Publish data using send
- Create a ZMQ::SUB socket and connect it to the publisher
- Set the filter of the received messages
- Receive messages with recv
Let assume that we have news for the revenue of Microsoft, Apple, Google and Oracle. Our publisher will broadcast news for all of these companies, but our subscriber is interested only in Google’s revenue:
Using setsockopt method we set the filter to get only news about Google. If we don’t provide filter, the subscriber wont’ get any news. If we set the filter to empty string, the subscriber will get all the news form the publisher.
Simple enough - bidirectional communication, no routing or filtering. Looks like regular socket. ZMQ::PAIR socket can only be connected to a single peer.
In the next chapter I’ll use the knowledge of this one to write a simple Hello World app in Ruby - a chat server. Stay tuned.
PS: Feel free to write me at mitko.kostov[at]gmail.com if you find some rubbish statement.