Skip to content

Instantly share code, notes, and snippets.

@sohang3112
Created July 24, 2024 00:59
Show Gist options
  • Save sohang3112/a8bd0e03eb6549cb756a952ac9c827fe to your computer and use it in GitHub Desktop.
Save sohang3112/a8bd0e03eb6549cb756a952ac9c827fe to your computer and use it in GitHub Desktop.

Zeromq example in Haskell

Zeromq client & server example in Haskell using zeromq4-haskell package (a Haskell wrapper over libzmq).

NOTE: In 2023 my PR was merged that added this Haskell example to zeromq.org website. But it doesn't show yet on zeromq.org website because the site owner hasn't yet updated the site according to the latest changes in its Github repo. You can also see the below example client & server in the Zeromq Github repository.

Server

-- This lets us conviniently use efficient ByteString to send and recieve messages
{-# LANGUAGE OverloadedStrings #-}         

{-
   Hello World server in Haskell
   Binds REP socket to tcp://*:5555
   Expects "Hello" from client, replies with "World"
-}

import System.ZMQ4.Monadic (runZMQ, socket, bind, send, receive, Socket, Rep(..))
import Control.Monad (forever)
import Control.Monad.IO.Class (liftIO)
import Control.Concurrent (threadDelay)
import Data.ByteString.Char8 (pack, unpack)

main :: IO ()
main = runZMQ $ do
    repSocket <- socket Rep
    bind repSocket "tcp://*:5555"
    forever $ do
        --  Wait for next request from client
        message <- receive repSocket
        liftIO $ putStrLn ("Received request: " ++ unpack message)

        --  Do some 'work' (waiting for 1 second here)
        liftIO $ threadDelay (1 * 1000000)

        --  Send reply back to client
        send repSocket [] (pack "World")

Client

-- This lets us conviniently use efficient ByteString to send and recieve messages
{-# LANGUAGE OverloadedStrings #-}

{-
   Hello World client in Haskell
   Connects REQ socket to tcp://localhost:5555
   Sends "Hello" to server, expects "World" back
-}

import System.ZMQ4.Monadic (runZMQ, socket, connect, send, receive, Socket, Req(..))
import Control.Monad (forM_)
import Control.Monad.IO.Class (liftIO)
import Data.ByteString.Char8 (pack, unpack)

main :: IO ()
main = runZMQ $ do
    --  Socket to talk to server
    reqSocket <- socket Req
    connect reqSocket "tcp://localhost:5555"

    --  Do 10 requests, waiting each time for a response
    forM_ [1..10] $ \i -> do
        liftIO $ putStrLn ("Sending request " ++ show i ++ "...")
        send reqSocket [] (pack "Hello")

        --  Get the reply
        message <- receive reqSocket
        liftIO $ putStrLn ("Received reply " ++ show i ++ " [" ++ unpack message ++ "]")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment