omu_negru
omu_negru

Reputation: 4770

Haskell ZeroMQ binding not working for REQ socket

So here i was, barely able to install the libzmq on a windows desktop and then zeromq-haskell with cabal. I wanted to test the api by binding a python program with a haskell program in a hello-world type application.

So the most basic pattern i see is the request-reply pattern . First i tried to make the server in haskell (REP) and the client in python (REQ), witch failed miserably no matter what i did. The generated exception message was Exception: receive: failed (No error).

So i look inside the System.ZMQ and System.ZMQ.Base source code and i see that receive throws an error on calling c_zmq_recv , witch in turn maps directly to a ffi (?) call to the C api. So i think perhaps i didn't do the installation properly , but then i try to make the client in Haskell and the server in python and i notice it works without any problem, so perhaps the recv interface isn't the problem here.

Here is the haskell code below , with both client and server functions

import System.ZMQ
import Control.Monad (forM_,forever)
import Data.ByteString.Char8 (pack,unpack)
import Control.Concurrent (threadDelay)

clientMain :: IO ()
clientMain = withContext 1 (\context->do
    putStrLn "Connecting to server"
    withSocket context Req $ (\socket-> do
        connect socket "tcp://127.0.0.1:5554"
        putStrLn $ unwords ["Sending request"]
        send socket (pack "Hello...") []
        threadDelay (1*1000*1000)
        reply<-receive socket []
        putStrLn $ unwords ["Received response : ",unpack reply]))

serverMain :: IO ()
serverMain = withContext 1 (\context-> do
    putStrLn "Listening at 5554"
    withSocket context Rep $ (\socket-> do
        connect socket "tcp://127.0.0.1:5554"
        forever $ do 
            message<-receive socket [] -- this throws an IO Exception
            putStrLn $ unwords ["Received request : ",unpack message]
            threadDelay (1*1000*1000)
            send socket (pack "World") [] ))

main :: IO ()
main = serverMain -- replace with clientMain and it works

Now i really didn't get around to testing all other modes of communication (push/pull, subscribe/publish, pair etc.) and for what i need the python server/haskell client is probably better but i am curious about weather i'm doing something wrong or if any part of my code is broken in any way.

Thanks in advance

Upvotes: 4

Views: 661

Answers (1)

Ben Ford
Ben Ford

Reputation: 2087

You need to make one of the sockets (usually the server) bind, you seem to have them both connecting.

Try changing connect socket "tcp://127.0.0.1:5554" to bind socket "tcp://127.0.0.1:5554" in the serverMain function.

Upvotes: 2

Related Questions