This is hard to do, even in the C world, without a good API.
, POSIX, Haskell connect(3). :
O_NONBLOCK , () , . , connect() , . ~
-. , select(3), > . , , Linux.
. , C, Haskell. :
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Control.Concurrent
import Data.Conduit.Network
-- | A more sensible unit of measurement for thread delays
threadDelaySeconds :: Double -> IO ()
threadDelaySeconds secs =
threadDelay (ceiling $ secs * 1e6)
runTCPClientBounded :: ClientSettings -> Double -> (AppData -> IO ()) -> IO ()
runTCPClientBounded settings secs cont = do
race <- newChan
_ <- forkIO (timer race)
_ <- forkIO (runTCPClient settings (handleServer race))
winner <- readChan race
case winner of
Nothing ->
error "runTCPClientBounded: could not connect in time"
Just appdata ->
cont appdata
where
timer :: Chan (Maybe AppData) -> IO ()
timer chan = do
putStrLn ("runTCPClientBounded: waiting $n seconds: " ++ show secs)
threadDelaySeconds secs
writeChan chan Nothing
handleServer :: Chan (Maybe AppData) -> AppData -> IO ()
handleServer chan appdata =
writeChan chan (Just appdata)
main :: IO ()
main =
runTCPClientBounded (clientSettings 80 "1.2.3.4") 1 (const (putStrLn "connected to 1.2.3.4!"))
-- runTCPClientBounded (clientSettings 80 "example.com") 1 (const (putStrLn "connected to example.com!"))
, n - , runTCPClient. , ; connect(3) , . : , , , , runTCPClient , (, , , , ). .
!