on 260e31d help sign in
133 lines 4.0 kB history raw
1{-# LANGUAGE CPP #-}
2{-# LANGUAGE BangPatterns #-}
3{-# LANGUAGE FlexibleContexts #-}
4{-# LANGUAGE MagicHash #-}
5{-# LANGUAGE RecordWildCards #-}
6{-# LANGUAGE UnboxedTuples #-}
8#include "inline.hs"
10-- |
11-- Module : Streamly.Network.Client
12-- Copyright : (c) 2019 Composewell Technologies
13--
14-- License : BSD3
15-- Maintainer : harendra.kumar@gmail.com
16-- Stability : experimental
17-- Portability : GHC
18--
19-- Combinators to build network clients.
20--
21-- > import qualified Streamly.Network.Socket as Client
22--
24module Streamly.Network.Client
25 (
26 -- * Interact
27 -- | Socket based reads and writes.
28 withConnection
30 -- * Source
31 , read
32 -- , readUtf8
33 -- , readLines
34 -- , readFrames
35 -- , readByChunks
37 -- -- * Array Read
38 -- , readArrayUpto
39 -- , readArrayOf
41 -- , readArraysUpto
42 -- , readArraysOf
43 -- , readArrays
45 -- * Sink
46 , write
47 -- , writeUtf8
48 -- , writeUtf8ByLines
49 -- , writeByFrames
50 -- , writeByChunks
52 -- -- * Array Write
53 -- , writeArray
54 , writeArrays
55 )
56where
58import Control.Monad.Catch (MonadCatch)
59import Control.Monad.IO.Class (MonadIO(..))
60import Data.Word (Word8)
61import Network.Socket
62 (Socket, PortNumber, Family(..), SockAddr(..), SocketType(..),
63 socket, connect, defaultProtocol)
64import Prelude hiding (read)
66import qualified Network.Socket as Net
68import Streamly (MonadAsync)
69import Streamly.Mem.Array.Types (Array(..))
70import Streamly.Streams.Serial (SerialT)
71import Streamly.Streams.StreamK.Type (IsStream)
73import qualified Streamly.Prelude as S
74import qualified Streamly.Network.Socket as SK
76-------------------------------------------------------------------------------
77-- Connect
78-------------------------------------------------------------------------------
80openConnection :: (Word8, Word8, Word8, Word8) -> PortNumber -> IO Socket
81openConnection addr port = do
82 sock <- socket AF_INET Stream defaultProtocol
83 connect sock $ SockAddrInet port (Net.tupleToHostAddress addr)
84 return sock
86-- | @'withConnection' addr port act@ opens a connection to the specified IPv4
87-- host address and port and passes the resulting socket handle to the
88-- computation @act@. The handle will be closed on exit from 'withConnection',
89-- whether by normal termination or by raising an exception. If closing the
90-- handle raises an exception, then this exception will be raised by
91-- 'withConnection' rather than any exception raised by 'act'.
92--
93-- @since 0.7.0
94withConnection :: (IsStream t, MonadCatch m, MonadIO m)
95 => (Word8, Word8, Word8, Word8) -> PortNumber -> (Socket -> t m a) -> t m a
96withConnection addr port =
97 S.bracket (liftIO $ openConnection addr port) (liftIO . Net.close)
99-------------------------------------------------------------------------------
100-- Read Addr to Stream
101-------------------------------------------------------------------------------
103-- | Read a stream from the supplied IPv4 host address and port number.
104--
105-- @since 0.7.0
106read :: (IsStream t, MonadCatch m, MonadIO m)
107 => (Word8, Word8, Word8, Word8) -> PortNumber -> t m Word8
108read addr port = withConnection addr port SK.read
110-------------------------------------------------------------------------------
111-- Writing
112-------------------------------------------------------------------------------
114-- | Write a stream to the supplied IPv4 host address and port number.
115--
116-- @since 0.7.0
117write :: (MonadCatch m, MonadIO m)
118 => (Word8, Word8, Word8, Word8) -> PortNumber -> SerialT m Word8 -> m ()
119write addr port xs =
120 S.drain $ withConnection addr port (\sk -> S.yieldM $ SK.write sk xs)
122-- | Write a stream of arrays to the supplied IPv4 host address and port
123-- number.
124--
125-- @since 0.7.0
126writeArrays
127 :: (MonadCatch m, MonadAsync m)
128 => (Word8, Word8, Word8, Word8)
129 -> PortNumber
130 -> SerialT m (Array Word8)
131 -> m ()
132writeArrays addr port xs =
133 S.drain $ withConnection addr port (\sk -> S.yieldM $ SK.writeArrays sk xs)