WS Module comments.

beta
Philippe Pittoli 2024-02-07 16:48:19 +01:00
parent 5a987a524c
commit c9c1b81912
1 changed files with 25 additions and 11 deletions

View File

@ -1,7 +1,7 @@
-- | This component handles all WS operations.
-- | This includes telling when a connection is established or closed, and notify a message has been received.
module App.WS where module App.WS where
{- This component handles all WS operations. -}
import Prelude (Unit, bind, discard, pure, show, void, when, ($), (&&), (<$>), (<>), (>>=), (>=>), (<<<), map) import Prelude (Unit, bind, discard, pure, show, void, when, ($), (&&), (<$>), (<>), (>>=), (>=>), (<<<), map)
import Control.Monad.Except (runExcept) import Control.Monad.Except (runExcept)
@ -30,38 +30,53 @@ import Web.Socket.WebSocket as WS
import App.LogMessage import App.LogMessage
-- Input is the WS url. -- Input is the WS url.
type Input = String type Input = String
-- MessageReceived (Tuple URL message) -- | The component can perform 4 actions: log messages, notify that a message has been received,
-- | notify when a connection has been established or when it has been closed.
data Output data Output
-- | MessageReceived (Tuple URL message)
= MessageReceived (Tuple String ArrayBuffer) -- Provide a received message to the parent. = MessageReceived (Tuple String ArrayBuffer) -- Provide a received message to the parent.
| WSJustConnected -- Inform the parent the connection is up. | WSJustConnected -- Inform the parent the connection is up.
| WSJustClosed -- Inform the parent the connection is down. | WSJustClosed -- Inform the parent the connection is down.
| Log LogMessage | Log LogMessage
-- | The component can receive a single action from other components: sending a message throught the websocket.
data Query a = ToSend ArrayBuffer a
type Slot = H.Slot Query Output type Slot = H.Slot Query Output
data Query a
= ToSend ArrayBuffer a
data Action data Action
-- | `Initialize` opens the connection (URL is received as an `input` of this component).
= Initialize = Initialize
-- | The component provides a log each time a message failed to be parsed.
| WebSocketParseError String | WebSocketParseError String
-- | The component shows buttons when the connection is dropped for some reason.
-- | To reconnect, the button is clicked, and the `ConnectWebSocket` action is performed.
| ConnectWebSocket | ConnectWebSocket
-- | `SendMessage` effectively sends a message through the ws connection.
| SendMessage ArrayBuffer | SendMessage ArrayBuffer
-- | `Finalize` is the action performed once the component is destroyed, ending the connection.
| Finalize | Finalize
-- | Every received websocket message and notification is handled in `HandleWebSocket`.
| HandleWebSocket (WebSocketEvent WebSocketMessageType) | HandleWebSocket (WebSocketEvent WebSocketMessageType)
-- | The type `WSInfo` helps handle a websocket.
-- | `WSInfo` is composed of an URL, an actual socket and a boolean
-- | to inform if the connection has to be re-established.
type WSInfo type WSInfo
= { url :: String = { url :: String
, connection :: Maybe WS.WebSocket , connection :: Maybe WS.WebSocket
, reconnect :: Boolean , reconnect :: Boolean
} }
-- | The state of this component only is composed of the websocket.
type State = { wsInfo :: WSInfo } type State = { wsInfo :: WSInfo }
component :: forall m. MonadAff m => H.Component Query Input Output m component :: forall m. MonadAff m => H.Component Query Input Output m
@ -85,6 +100,7 @@ initialState url =
} }
} }
-- | The component shows a string when the connection is established, or a button when the connection has closed.
render :: forall m. State -> H.ComponentHTML Action () m render :: forall m. State -> H.ComponentHTML Action () m
render { wsInfo } render { wsInfo }
= HH.div_ = HH.div_
@ -149,11 +165,9 @@ handleAction action = do
HandleWebSocket wsEvent -> do HandleWebSocket wsEvent -> do
case wsEvent of case wsEvent of
WebSocketMessage received_message -> do WebSocketMessage received_message -> do
-- H.raise $ Log $ SimpleLog $ "[😈] Received a message"
H.raise $ MessageReceived $ Tuple wsInfo.url received_message.message H.raise $ MessageReceived $ Tuple wsInfo.url received_message.message
WebSocketOpen -> do WebSocketOpen -> do
-- H.raise $ Log $ SystemLog ("Successfully connected to \"" <> wsInfo.url <> "\"!🎉")
H.raise $ WSJustConnected H.raise $ WSJustConnected
WebSocketClose { code, reason, wasClean } -> do WebSocketClose { code, reason, wasClean } -> do
@ -163,9 +177,9 @@ handleAction action = do
H.modify_ _ { wsInfo { connection = Nothing, reconnect = true } } H.modify_ _ { wsInfo { connection = Nothing, reconnect = true } }
H.raise $ WSJustClosed H.raise $ WSJustClosed
WebSocketError errorType -> WebSocketError errorType -> do
H.raise $ Log $ SystemLog $ renderError errorType H.raise $ Log $ SystemLog $ renderError errorType
-- TODO: MAYBE inform the parent the connection is closed (if it's the case). H.raise $ WSJustClosed
where where
renderCloseMessage renderCloseMessage