Interacting with ZeroMQ from the browser is the talk me and my co-worker Jeff Lindsay gave at ZeroMQ conference in Portland, OR. We've missed our flight the night before and I started writing this post while we had been sitting at the gate, waiting for unclaimed seats on the next available flight.
Fixing the world
"World is broken" is the reason ZeroMQ exists, it is there because networking has been unnecessarily hard and had to be fixed. ZeroMQ's philosophy is about modularity and reusability, it promotes creation and use of sockets, networking primitives, that do just one thing and do it well, to compose more complex communication patterns that are simple to think about and communicate.
ZeroMQ in the browser
Design and philosophy of ZeroMQ alone is incredibly useful and opens up mind to new ways of thinking about and solving networking problems. From this point of view, ZeroMQ's actual C library (libzmq) is just an implementation detail. Imagine taking same networking primitives ZeroMQ introduces and solving web related problems with them. NullMQ is taking concepts ZeroMQ introduced and applying them in a different environment. This new environment has a different set of constraints, yet similar requirements of solving communication by reusing basic primitives.
NullMQ gives you the same six socket types to be used in the browser. Browser environment is different from private networks. Additional constraints like authentication, authorization, limited number of connections and speed are added. NullMQ operates over WebSockets and has its own communication protocol based on STOMP. NullMQ to STOMP is like WebDav to HTTP. It is therefore server implementation agnostic. NullMQ context, once instantiated, lets you create same socket types as regular ZeroMQ context. It won't open new connection per each socket however and will instead handle multiplexing of connections,so you get multiple virtual connections, all using one real connection underneath. Having ZeroMQ semantics available in the browser is powerful, because it lets you solve a networking problem by designing appropriate communication pattern from scratch, without being constrained by various browser or server networking specifics, and re-use it in both environments.
NullMQ in action
For our NullMQ demo I build chat and presence servers and clients. For both problems, I used clone pattern from ZeroMQ guide. Server in clone pattern consists of three different sockets, PUB - which is used to publish state updates to all subscribed clients, PULL - which each individual client pushes its state changes to, and which server ultimately ends up publishing to all clients and, finally, ROUTER - which is used to answer client requests to get server's current absolute state. Client also has three sockets, which are almost exact opposites of server's socket set. When client first starts, it uses a SUB socket to subscribe to all state changes that a server will publish, immediately after that, it creates a REQ socket to get server's current absolute state which it will then remember and apply published updates to to stay in sync, and, finally it uses a PUSH socket to send it's own state changes back to the server.
This pattern solves both a chat and a presence use case. In case of a chat, a clients connects, subscribes to new messages and requests all messages previously published to the server. Whenever user sends a message, it pushes them back to the server, server publishes this message to all clients and it ends up on user's screen. In case of a presence server, client connects, subscribes to peers' state updates from the server, requests a list of all peers, which is a list of names and online statuses and starts pushing periodic heartbeat. In my case, it specifies heartbeat timeout in every heartbeat message and server constantly looks at a list of registered clients, checks when the last heartbeat for each client was received and compares it to a timeout that client send out. If more time has passed since the last heartbeat than was specified as timeout, it decides the client is offline and publishes that to others.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
The joy of realtime
While being a great networking library, ZeroMQ is more than that, it is a networking philosophy and a great source of recipes for common problems. NullMQ proves that this philosophy and knowledge is not limited to traditional, private networking, but also weird, limited control places like web browsers. So take it for a spin and let me know how it goes.
P.S. all sources for our presence and chat demo are available on github, just follow the docs in each directory to be able to run it locally.