{-# LANGUAGE RankNTypes #-}
-- | This module offers tools to stream from and to WebSocket
-- 'W.Connection's using "Pipes".
--
-- See the
-- [network-simple-wss](https://hackage.haskell.org/package/network-simple-wss),
-- [network-simple-ws](https://hackage.haskell.org/package/network-simple-ws) or
-- and [websockets](https://hackage.haskell.org/package/websockets)
-- libraries as well, for lower level support.
module Pipes.Network.WS
( fromConnection
, toConnection
) where
import Control.Monad.IO.Class (MonadIO)
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as BL
import Data.Function (fix)
import qualified Pipes as P
import qualified Network.Simple.WS as WS
--------------------------------------------------------------------------------
-- | Receives bytes from the remote end and sends them downstream.
--
-- The obtailed 'B.ByteString's are never 'B.empty'.
--
-- This producer returns when the conection is closed gracefully.
-- Note: The WebSockets protocol supports the silly idea of sending text, rather
-- than bytes, over the socket. We don't support that. If necessary, users can
-- find support for this in the `websockets` library.
fromConnection
:: MonadIO m
=> WS.Connection
-> P.Producer' B.ByteString m () -- ^
{-# INLINABLE fromConnection #-}
fromConnection conn =
fix $ \k -> do
bs <- WS.recv conn
case B.null bs of
False -> P.yield bs >> k
True -> pure ()
-- | Send bytes from upstream to the remote end.
-- Note: The WebSockets protocol supports the silly idea of sending text, rather
-- than bytes, over the socket. We don't support that. If necessary, users can
-- find support for this in the `websockets` library.
toConnection
:: MonadIO m
=> WS.Connection
-> P.Consumer' B.ByteString m () -- ^
{-# INLINABLE toConnection #-}
toConnection conn = P.for P.cat (WS.send conn . BL.fromStrict)