Wednesday, September 18, 2013

ZeroMQ

ZeroMQ is a "high-level" socket library that provides some middleware capabilities and markets itself as "The Simplest Way to Connect Pieces".

About a year ago, Eungju Park created a binding that was usable from Factor. He was gracious to allow us to merge his vocabulary into the main repository. In the process, I cleaned up the API a little bit and made sure it works with the latest version of ZeroMQ (currently 3.2.3).

As a quick tease, I thought I would show off a simple "echo" example.

echo

Our "echo" server will bind to port 5000. It will loop forever, sending any messages that it receives back to the client:

: echo-server ( -- )
    [
        <zmq-context> &dispose
        ZMQ_REP <zmq-socket> &dispose
        dup "tcp://127.0.0.1:5000" zmq-bind
        [ dup 0 zmq-recv dupd 0 zmq-send t ] loop
        drop
    ] with-destructors ;

Our "echo" client will connect to the server on port 5000. Each second, we grab the current time (by calling now), format it into as string and send it to the server, printing the message being sent and the message that was received:

: echo-client ( -- )
    [
        <zmq-context> &dispose
        ZMQ_REQ <zmq-socket> &dispose
        dup "tcp://127.0.0.1:5000" zmq-connect
        [
            now present
            [ "Sending " write print flush ]
            [ >byte-array dupd 0 zmq-send ] bi
            dup 0 zmq-recv >string
            "Received " write print flush
            1 seconds sleep
            t
        ] loop
        drop
    ] with-destructors ;

Perhaps not as simple as a pure Factor echo server, but all the nuts and bolts are working. Maybe in the future we could write a wrapper for a wrapper to simplify using ZeroMQ in common use-cases.

The zeromq vocabulary and several other examples of its use are available in the latest development version of Factor.

Note: the calls into the ZeroMQ are blocking in such a way that we have to run the echo-server in one Factor process and the echo-client in another Factor process. It would be nice to integrate it in such a way this was not necessary.

No comments: