------------------------------------------------------------------------------- -- | -- Module : Network/Mom/Patterns/Basic/Server.hs -- Copyright : (c) Tobias Schoofs -- License : LGPL -- Stability : experimental -- Portability: non-portable -- -- Server side of \'Client\/Server\' ------------------------------------------------------------------------------- module Network.Mom.Patterns.Basic.Server ( -- * Server withServer, -- * Queue withQueue) where import Data.Conduit ((=$)) import Network.Mom.Patterns.Types import Network.Mom.Patterns.Streams ------------------------------------------------------------------------ -- | Start a server as a background process -- -- * 'Context' - The zeromq context -- -- * 'Service' - Service name -- -- * 'String' - The address to link to -- -- * 'LinkType' - Whether to connect to or to bind the address -- -- * 'OnError_' - Error handler -- -- * 'Conduit_' - The application-defined stream transformer; -- the conduit receives the request as input stream -- and should create the output stream that is -- internally sent back to the client -- -- * 'Control' a - Control action -- -- A very simple example, which just sends the incoming stream -- back to the client ('bounce'): -- -- > import Control.Monad (forever) -- > import Control.Concurrent -- > import Network.Mom.Patterns.Basic.Server -- > import Network.Mom.Patterns.Types -- -- > main :: IO () -- > main = withContext 1 $ \ctx -> -- > withServer ctx "Bouncer" "tcp://*:5555" Bind -- > (\_ _ _ -> return ()) -- ignore error -- > bounce $ \_ -> forever $ threadDelay 100000 -- > where bounce = passThrough ------------------------------------------------------------------------ withServer :: Context -> Service -> String -> LinkType -> OnError_ -> Conduit_ -> Control a -> IO a withServer ctx srv add lt onErr serve = withStreams ctx srv (-1) [Poll "client" add DealerT lt [] []] igTmo onErr job where job s = serve =$ passAll s ["client"] igTmo _ = return () ------------------------------------------------------------------------ -- | A simple load balancer device to link clients and servers. -- -- * 'Context' - The zeromq context -- -- * 'Service' - The service name of this queue -- -- * (String, 'LinkType') - Address and link type, to where clients -- connect. Note if clients connect, -- the queue must bind the address! -- -- * (String, 'LinkType') - Address and link type, to where servers -- connect. Note, again, that -- if servers connect, the queue must -- bind the address! -- -- * 'OnError_' - Error handler -- -- * 'Control' a - 'Controller' action ------------------------------------------------------------------------ withQueue :: Context -> Service -> (String, LinkType) -> (String, LinkType) -> OnError_ -> Control a -> IO a withQueue ctx srv (rout, routl) (deal, deall) onErr = withStreams ctx srv (-1) [Poll "client" rout RouterT routl [] [], Poll "server" deal DealerT deall [] []] onTmo onErr job where job s = let target | getSource s == "client" = "server" | otherwise = "client" in passAll s [target] onTmo _ = return ()