Thursday, January 10, 2008

More haskell simple networking client code and connecting to RabbitMQ

Well, I have made a little bit more progress with the simple haskell network client and connected to a RabbitMQ server and received some of a valid response. What makes this example a little bit different than a simple echo client/server connection is that a AMQP client needs to send valid byte responses in big endian format. For example, the first 1 octet that must be sent to the server include this header BYTE:'A', BYTE:'M', BYTE:'Q', BYTE:'P', BYTE:1, BYTE:9, BYTE:1, BYTE:1. Bytes are easy, but sending short values and also sending unicode responses requires a little bit of work. The java client library provided by RabbitMQ as you might have guess makes sending unicode or byte packages straightforward. In haskell, well there just isn't a lot of code out there that demonstrates how to do this. With that being said, here is some update to the simple client. At first I wanted to just demonstrate networking in haskell, but now I may go a step forward in working on a usable RabbitMQ client (time permitting of course).

Key code snippet:
The following uses the Data.Binary.Get monad to receive frame data back from the rabbit mq server. Get a frame type, channel, size of the payload and then the payload byte data.

instance Binary AMQPFrame where
get = do
frameType <- getWord8
chan <- getWord16be
sz <- getWord32be
bytes <- BinaryGet.getLazyByteString (fromIntegral sz)
chw <- getWord8
return (AMQPFrame { frameType=frameType,


You can see the python example, just imagine porting the python library to haskell. Syntactically, with haskell we can use some of the code verbatim. For example, look at the METHOD_MAP_NAME in the python code and compare that with the pattern matching in the haskell source.

No comments: