I wrote a test program (and first "real" Haskell program!) that receives a zmq request on 1 socket, and forwards part of that message to another socket.
There are a 2 things I specifically don't like:
- I couldn't figure out a way to build a protobuf message without specifying every field. This is especially annoying for fields like
failure_message
, which I had to set toNothing
- I'm not a fan of the lazyToStrictBS conversion
Is there any way to avoid these? Also, any other things I should fix? I would be shocked if there were no other issues.
The code:
module Main where
import System.ZMQ4.Monadic
import Control.Monad (forever)
import Data.ByteString.Char8 (pack, unpack)
import qualified Data.ByteString as ByteString (ByteString, concat)
import Data.ByteString.Lazy as LBS (ByteString, toChunks)
import Control.Concurrent (threadDelay)
import Text.ProtocolBuffers.WireMessage (messageGet)
import Text.ProtocolBuffers.WireMessage (messagePut)
import ProtoMsg.ForwardRequest (ForwardRequest)
import ProtoMsg.ForwardResponse
import ProtoMsg.ReqResponse (ReqResponse)
import ProtoMsg.Status
import ProtoMsg.Retort
lazyToStrictBS :: LBS.ByteString -> ByteString.ByteString
lazyToStrictBS x = ByteString.concat $ LBS.toChunks x
main :: IO ()
main =
runZMQ $ do
repSocket <- socket Rep
bind repSocket "tcp://*:9000"
pubSocket <- socket Pub
bind pubSocket "tcp://*:9001"
liftIO $ putStrLn "Ready"
forever $ do
msg <- receive repSocket
(liftIO.putStrLn.unwords) ["Received request:", unpack msg]
let repMsg = ProtoMsg.ForwardResponse.ForwardResponse {
header = ProtoMsg.ReqResponse.ReqResponse {
message_id = Nothing,
user_id = Nothing,
request_id = Nothing,
ProtoMsg.ReqResponse.status = Just ProtoMsg.Status.OK,
failure_message = Nothing
}
}
let respMsg = ProtoMsg.Retort.Retort {
status = Just ProtoMsg.Status.OK,
failure_message = Nothing
}
send repSocket [] (lazyToStrictBS (messagePut respMsg))