0MQ and Haskell
Ever since I heard the FLOSS weekly episode on 0MQ I’ve been looking for a reason to take a look at it. Well, to hell with reason, I’ll have a first look without any specific goal in mind.
I found a simple introduction to it in Nicholas PiĆ«l’s post ZeroMQ an introduction. The only issue was that it was based on Python, and Python2 at that. So here are my attempts at translating two of the clients to Haskell (using zeromq-haskell).
req-rep
Here’s the client in Python3 first:
1 2 3 4 5 6 7 8 9 10 11 | import zmq ctx = zmq.Context() socket = ctx.socket(zmq.REQ) socket.connect('tcp://127.0.0.1:5000') for i in range(10): msg = "msg %s" % i socket.send_unicode(msg) print('Sending', msg) msg_in = socket.recv() |
And here in Haskell:
1 2 3 4 5 6 7 8 9 10 | import System.ZMQ import Data.ByteString.Char8 as CBS main = withContext 1 $ \ ctx -> withSocket ctx Req $ \ soc -> do connect soc "tcp://127.0.0.1:5000" let msgs = [pack ("msg " ++ show i) | i <- [0..9]] flip mapM_ msgs $ \ msg -> do send soc msg [] CBS.putStrLn msg receive soc [] |
pub-sub
In Python3:
1 2 3 4 5 6 7 8 9 10 | import zmq ctx = zmq.Context() socket = ctx.socket(zmq.SUB) socket.connect('tcp://127.0.0.1:5000') socket.setsockopt(zmq.SUBSCRIBE, b'sweden') socket.setsockopt(zmq.SUBSCRIBE, b'denmark') while True: print(socket.recv()) |
Haskell:
1 2 3 4 5 6 7 8 9 | import System.ZMQ import Control.Monad import Data.ByteString.Char8 as CBS main = withContext 1 $ \ ctx -> withSocket ctx Sub $ \ soc -> do connect soc "tcp://127.0.0.1:5000" subscribe soc "sweden" subscribe soc "denmark" forever $ receive soc [] >>= CBS.putStrLn |
Two comments on the Haskell code here:
- I’m not sure why, but the Haskell client dies after receiving just a few messages (they are properly filtered though).
- The API for
subscribeis a bit strange, it would make more sense if it took aByteStringrather than aString.