I am planning to dive into the details on ZMQ patterns, sockets and all other fancy stuff zeromq
offers so I need to find the best way to write disposable code which allows me to get the learn-test-understand loop as quick as possible. I find the best language for doing that quick&dirty PoCs (or tests) is python
so I have created a docker image with the required zeromq
libraries and the Python binding installed. This way I can write code in my local environment without needing to install zeromq-related things and I can run it in a ready-to-use (and also throw away) environment.
Creating a Docker Machine to work with
This guide assumes you have installed docker
(I am using v1.9.1) and docker-machine
(I am using v0.5.1) running on OS X (El Capitan).
Create a virtualbox
instance with docker engine running on it. Inside the VM we will run our programs:
docker-machine create -d virtualbox dm-pyzmq
Then, set up the shell environment variables to point to the just created docker machine:
eval $(docker-machine env dm-pyzmq)
This way, each docker
command will be using the docker engine running on the VM named dm-pyzmq
.
Test the environment
As already said, we are going to use an image called zmq-pyzmq. We also need to create a couple of simple python programs that I am going to use for testing the workflow. I am going to use this basic chat program. In order to make things easier, I am going to write them here. So first, create a new folder like this:
mkdir pyzmq-test
cd pyzmq-test
Now, let's create a simple program for displaying messages received from a socket.
cat > display.py
Copy and paste this code into the shell console and press CTRL+D
when done.
import zmq
def main(addrs):
context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.setsockopt(zmq.SUBSCRIBE, "")
for addr in addrs:
print "Connecting to: ", addr
socket.connect(addr)
while True:
msg = socket.recv_pyobj()
print "%s: %s" % (msg[1], msg[0])
if __name__ == '__main__':
import sys
if len(sys.argv) < 2:
print "usage: display.py <address> [,<address>...]"
raise SystemExit
main(sys.argv[1:])
The other program to be created will prompt you to enter messages.
cat > prompt.py
Copy and paste this code into the shell console and press CTRL+D
when done.
import zmq
def main(addr, who):
ctx = zmq.Context()
socket = ctx.socket(zmq.PUB)
socket.bind(addr)
while True:
msg = raw_input("%s> " % who)
socket.send_pyobj((msg, who))
if __name__ == '__main__':
import sys
if len(sys.argv) != 3:
print "usage: prompt.py <address> <username>"
raise SystemExit
main(sys.argv[1], sys.argv[2])
Once done, you should open a new shell session because we will need two programs to be launched. First thing to do will be to create a private network for them to be able to connect. And we will use docker for that too:
docker network create my_net
This will allow us to use container names for connecting one container to the other.
eval $(docker-machine env dm-pyzmq)
docker run -it --name prompt --net my_net -v `pwd`:/project oscarmartin/zmq-pyzmq prompt.py "tcp://*:5000" user1
This will create a prompt for entering messages. Do not do anything right now there but keep it open. On the former shell session, execute this:
docker run -it --net my_net -v `pwd`:/project oscarmartin/zmq-pyzmq display.py "tcp://prompt:5000"
This will connect to the first prompt
docker and will echo what it receives from there, so let's try it. Go back to the session where the prompt was expecting some input and write "Hello World!", like this:
user1> Hello World!
If you go to the session where display
docker is running on, you will hopefully see the message too:
user1: Hello World!
So this is the environment I will use to learn about ZeroMQ.