hasbolt-0.1.2.1: src/Database/Bolt/Connection/Socket.hs
module Database.Bolt.Connection.Socket
( Socket
, connectSock, closeSock
, recv, send, sendMany
) where
import Control.Exception (bracketOnError)
import Control.Monad.IO.Class (MonadIO (..))
import Data.ByteString (ByteString, null)
import Network.Socket (AddrInfoFlag (..), HostName,
ServiceName, SockAddr, Socket,
SocketType (..), addrAddress,
addrFamily, addrFlags, addrProtocol,
addrSocketType, defaultHints,
getAddrInfo, socket, close, connect)
import qualified Network.Socket.ByteString as NSB (recv, sendAll, sendMany)
import Prelude hiding (null)
connectSock :: MonadIO m => HostName -> ServiceName -> m (Socket, SockAddr)
connectSock host port = liftIO $ bracketOnError (createSock host port) (closeSock . fst) $
\(sock, addr) -> liftIO (connect sock addr) >> pure (sock, addr)
createSock :: MonadIO m => HostName -> ServiceName -> m (Socket, SockAddr)
createSock host port = liftIO $ do (addr:_) <- getAddrInfo (Just hints) (Just host) (Just port)
let family' = addrFamily addr
let type' = addrSocketType addr
let protocol' = addrProtocol addr
sock <- socket family' type' protocol'
pure (sock, addrAddress addr)
where hints = defaultHints { addrFlags = [AI_ADDRCONFIG]
, addrSocketType = Stream
}
closeSock :: MonadIO m => Socket -> m ()
closeSock = liftIO . close
recv :: MonadIO m => Socket -> Int -> m (Maybe ByteString)
recv sock nbytes = liftIO $ do bs <- NSB.recv sock nbytes
if null bs then pure Nothing
else pure (Just bs)
send :: MonadIO m => Socket -> ByteString -> m ()
send sock = liftIO . NSB.sendAll sock
sendMany :: MonadIO m => Socket -> [ByteString] -> m ()
sendMany sock = liftIO . NSB.sendMany sock