2{-# LANGUAGE BangPatterns #-}
3{-# LANGUAGE FlexibleContexts #-}
4{-# LANGUAGE MagicHash #-}
5{-# LANGUAGE RecordWildCards #-}
6{-# LANGUAGE UnboxedTuples #-}
11-- Module : Streamly.Network.Client
12-- Copyright : (c) 2019 Composewell Technologies
15-- Maintainer : harendra.kumar@gmail.com
16-- Stability : experimental
19-- Combinators to build network clients.
21-- > import qualified Streamly.Network.Socket as Client
24module Streamly.Network.Client
27 -- | Socket based reads and writes.
58import Control.Monad.Catch (MonadCatch)
59import Control.Monad.IO.Class (MonadIO(..))
60import Data.Word (Word8)
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.Internal.Data.Fold.Types (Fold(..))
70import Streamly.Internal.Memory.Array.Types (Array(..), defaultChunkSize, writeNUnsafe)
71-- import Streamly.Streams.Serial (SerialT)
72import Streamly.Streams.StreamK.Type (IsStream)
74import qualified Streamly.Internal.Memory.ArrayStream as AS
75import qualified Streamly.Internal.Data.Fold.Types as FL
76import qualified Streamly.Prelude as S
77import qualified Streamly.Network.Socket as SK
78import qualified Streamly.Internal.Network.Socket as ISK
80-------------------------------------------------------------------------------
82-------------------------------------------------------------------------------
84openConnection :: (Word8, Word8, Word8, Word8) -> PortNumber -> IO Socket
85openConnection addr port = do
86 sock <- socket AF_INET Stream defaultProtocol
87 connect sock $ SockAddrInet port (Net.tupleToHostAddress addr)
90-- | @'withConnection' addr port act@ opens a connection to the specified IPv4
91-- host address and port and passes the resulting socket handle to the
92-- computation @act@. The handle will be closed on exit from 'withConnection',
93-- whether by normal termination or by raising an exception. If closing the
94-- handle raises an exception, then this exception will be raised by
95-- 'withConnection' rather than any exception raised by 'act'.
98{-# INLINABLE withConnection #-}
99withConnection :: (IsStream t, MonadCatch m, MonadIO m)
100 => (Word8, Word8, Word8, Word8) -> PortNumber -> (Socket -> t m a) -> t m a
101withConnection addr port =
102 S.bracket (liftIO $ openConnection addr port) (liftIO . Net.close)
104-------------------------------------------------------------------------------
105-- Read Addr to Stream
106-------------------------------------------------------------------------------
108-- | Read a stream from the supplied IPv4 host address and port number.
112read :: (IsStream t, MonadCatch m, MonadIO m)
113 => (Word8, Word8, Word8, Word8) -> PortNumber -> t m Word8
114read addr port = AS.concat $ withConnection addr port ISK.toStreamArrays
116-------------------------------------------------------------------------------
118-------------------------------------------------------------------------------
121-- | Write a stream of arrays to the supplied IPv4 host address and port
125{-# INLINE writeArrays #-}
127 :: (MonadCatch m, MonadAsync m)
128 => (Word8, Word8, Word8, Word8)
130 -> SerialT m (Array Word8)
132writeArrays addr port xs =
133 S.drain $ withConnection addr port (\sk -> S.yieldM $ SK.writeArrays sk xs)
136-- | Write a stream of arrays to the supplied IPv4 host address and port
140{-# INLINE writeArrays #-}
143 => (Word8, Word8, Word8, Word8)
145 -> Fold m (Array Word8) ()
146writeArrays addr port = Fold step initial extract
149 skt <- liftIO (openConnection addr port)
150 FL.initialize (SK.writeArrays skt)
152 extract (Fold _ initial1 extract1) = initial1 >>= extract1
155-- | Like 'write' but provides control over the write buffer. Output will
156-- be written to the IO device as soon as we collect the specified number of
160{-# INLINE writeInChunksOf #-}
162 :: (MonadCatch m, MonadAsync m)
164 -> (Word8, Word8, Word8, Word8)
168writeInChunksOf n addr port m = writeArrays addr port $ AS.arraysOf n m
171-- | Like 'write' but provides control over the write buffer. Output will
172-- be written to the IO device as soon as we collect the specified number of
176{-# INLINE writeInChunksOf #-}
180 -> (Word8, Word8, Word8, Word8)
183writeInChunksOf n addr port =
184 FL.lchunksOf n (writeNUnsafe n) (writeArrays addr port)
187-- | Write a stream to the supplied IPv4 host address and port number.
191write :: (MonadCatch m, MonadAsync m)
192 => (Word8, Word8, Word8, Word8) -> PortNumber -> SerialT m Word8 -> m ()
193write = writeInChunksOf defaultChunkSize
196-- | Write a stream to the supplied IPv4 host address and port number.
201 => (Word8, Word8, Word8, Word8) -> PortNumber -> Fold m Word8 ()
202write = writeInChunksOf defaultChunkSize
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list