miso
Copyright(C) 2016-2026 David M. Johnson
LicenseBSD3-style (see the file LICENSE)
MaintainerDavid M. Johnson <code@dmj.io>
Stabilityexperimental
Portabilitynon-portable
Safe HaskellNone
LanguageHaskell2010

Miso.WebSocket

Description

Overview

Miso.WebSocket provides a full-duplex WebSocket client that integrates directly into the MVU loop. Every operation — connecting, sending, and closing — returns an Effect, making WebSocket communication a first-class citizen of the update function.

Quick start

import Miso
import Miso.WebSocket

data Action
  = Connect
  | Connected  WebSocket
  | Received   MisoString
  | Disconnected Closed
  | WsError    MisoString
  | Send       MisoString
  | Disconnect

-- Hold the socket handle in the model so we can send later
data Model = Model { ws :: WebSocket }

update :: Action -> Effect p props Model Action
update Connect =
  connectText "wss://echo.websocket.org"
    Connected Disconnected Received WsError
update (Connected sock) =
  modify (\m -> m { ws = sock })
update (Received msg) =
  io_ (consoleLog msg)
update (Send txt) = do
  sock <- gets ws
  sendText sock txt
update Disconnect = do
  sock <- gets ws
  close sock
update _ = pure ()

Connection variants

Five connect functions cover every wire format. They all share the same callback signature — onOpen, onClosed, onMessage, onError — but differ in how the message payload is decoded:

connectText
MisoString — plain UTF-8 text
connectJSON
json (FromJSON json) — auto-decoded from JSON
connectBLOB
Blob — raw binary Blob
connectArrayBuffer
ArrayBuffer — raw binary buffer
connect
Payload json — mixed; caller pattern-matches the payload ADT

Sending messages

The WebSocket handle delivered to onOpen must be stored in the model and passed to each send call:

sendText        :: WebSocket -> MisoString -> Effect p props model action
sendJSON        :: ToJSON json => WebSocket -> json -> Effect p props model action
sendBLOB        :: WebSocket -> Blob -> Effect p props model action
sendArrayBuffer :: WebSocket -> ArrayBuffer -> Effect p props model action

Lifecycle

  • Always call close when the connection is no longer needed to avoid resource leaks. It is safe to call close multiple times — subsequent calls are no-ops.
  • socketState lets you query the current SocketState (CONNECTING, OPEN, CLOSING, CLOSED) asynchronously.
  • emptyWebSocket (= -1) is a null sentinel you can store in the model before a connection has been established.

Types

See also

Synopsis

WebSocket

connect Source #

Arguments

:: FromJSON json 
=> URL

URL endpoint for a WebSocket connection

-> (WebSocket -> action)

onOpen callback w/ WebSocket object for successful connection. WebSocket is used here to send messages.

-> (Closed -> action)

onClosed method that is called when a WebSocket connection has closed.

-> (Payload json -> action)

onMessage is a callback invoked when a message has been received from the WebSocket server.

-> (MisoString -> action)

Error message callback

-> Effect parent props model action 

https://developer.mozilla.org/en-US/docs/Web/API/WebSocket

Establishes a WebSocket server that receives potentially multiple different Payload.

It's more common to use connectJSON or connectText. But connect can be used to received multiple different kinds of data from a WebSocket server.

connectJSON Source #

Arguments

:: FromJSON json 
=> URL

URL endpoint for a WebSocket connection

-> (WebSocket -> action)

onOpen callback w/ WebSocket object for successful connection. WebSocket is used here to send messages.

-> (Closed -> action)

onClosed method that is called when a WebSocket connection has closed.

-> (json -> action)

onMessage is a callback invoked when a JSON-encoded message has been received from the WebSocket server.

-> (MisoString -> action)

Error message callback

-> Effect parent props model action 

https://developer.mozilla.org/en-US/docs/Web/API/WebSocket

Establishes a WebSocket server that assumes a JSON-encoded protocol.

connectText Source #

Arguments

:: URL

URL endpoint for a WebSocket connection

-> (WebSocket -> action)

onOpen callback w/ WebSocket object for successful connection. WebSocket is used here to send messages.

-> (Closed -> action)

onClosed method that is called when a WebSocket connection has closed.

-> (MisoString -> action)

onMessage is a callback invoked when a text-encoded message has been received from the WebSocket server.

-> (MisoString -> action)

Error message callback

-> Effect parent props model action 

https://developer.mozilla.org/en-US/docs/Web/API/WebSocket

Establishes a WebSocket server that assumes a text-encoded protocol.

connectBLOB Source #

Arguments

:: URL

URL endpoint for a WebSocket connection

-> (WebSocket -> action)

onOpen callback w/ WebSocket object for successful connection. WebSocket is used here to send messages.

-> (Closed -> action)

onClosed method that is called when a WebSocket connection has closed.

-> (Blob -> action)

onMessage is a callback invoked when a binary-encoded message has been received from the WebSocket server.

-> (MisoString -> action)

onError callback

-> Effect parent props model action 

https://developer.mozilla.org/en-US/docs/Web/API/WebSocket

Establishes a WebSocket server that assumes a binary-encoded protocol.

connectArrayBuffer Source #

Arguments

:: URL

URL endpoint for a WebSocket connection

-> (WebSocket -> action)

onOpen callback w/ WebSocket object for successful connection. WebSocket is used here to send messages.

-> (Closed -> action)

onClosed method that is called when a WebSocket connection has closed.

-> (ArrayBuffer -> action)

onMessage is a callback invoked when an ArrayBuffer message has been received from the WebSocket server.

-> (MisoString -> action)

onError callback

-> Effect parent props model action 

sendText Source #

Arguments

:: WebSocket

WebSocket descriptor required to send a message to the server.

-> MisoString

A text payload to send to WebSocket server

-> Effect parent props model action 

sendJSON Source #

Arguments

:: ToJSON json 
=> WebSocket

WebSocket descriptor required to send a message to the server.

-> json

A JSON-encoded message

-> Effect parent props model action 

https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send

data Person = Person { name :: MisoString, age :: Int }
  deriving (Show, Eq)

instance ToJSON Person where
  toJSON (Person name age) = object [ "name" .= name, "age" .= age ]

test :: WebSocket -> Effect parent props model action
test connection = do
  sendJSON (connection :: WebSocket) (Person "alice" 42)
  sendJSON (connection :: WebSocket) (Person "bob" 42)

sendBLOB Source #

Arguments

:: WebSocket

WebSocket descriptor required to send a message to the server.

-> Blob

An Blob payload to send to the WebSocket server

-> Effect parent props model action 

sendArrayBuffer Source #

Arguments

:: WebSocket

WebSocket descriptor required to send a message to the server.

-> ArrayBuffer

An ArrayBuffer payload to send to the WebSocket server

-> Effect parent props model action 

close Source #

Arguments

:: WebSocket

WebSocket descriptor required to close the socket on the server.

-> Effect parent props model action 

https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/close

It is very important to close the WebSocket, otherwise leaks can occur.

close is a no-op if invoked multiple times.

socketState :: WebSocket -> (SocketState -> action) -> Effect parent props model action Source #

Retrieves current status of WebSocket

If the WebSocket identifier does not exist a CLOSED is returned.

Defaults

emptyWebSocket :: WebSocket Source #

A null WebSocket is one with a negative descriptor.

Types

newtype WebSocket Source #

Type for holding a WebSocket file descriptor.

Constructors

WebSocket Int 

Instances

Instances details
Num WebSocket Source # 
Instance details

Defined in Miso.Runtime

Eq WebSocket Source # 
Instance details

Defined in Miso.Runtime

ToJSVal WebSocket Source # 
Instance details

Defined in Miso.Runtime

type URL = MisoString Source #

URL that the WebSocket will connect to

data CloseCode Source #

Code corresponding to a closed connection https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent

Constructors

CLOSE_NORMAL

1000, Normal closure; the connection successfully completed whatever purpose for which it was created.

CLOSE_GOING_AWAY

1001, The endpoint is going away, either because of a server failure or because the browser is navigating away from the page that opened the connection.

CLOSE_PROTOCOL_ERROR

1002, The endpoint is terminating the connection due to a protocol error.

CLOSE_UNSUPPORTED

1003, The connection is being terminated because the endpoint received data of a type it cannot accept (for example, a textonly endpoint received binary data).

CLOSE_NO_STATUS

1005, Reserved. Indicates that no status code was provided even though one was expected.

CLOSE_ABNORMAL

1006, Reserved. Used to indicate that a connection was closed abnormally (that is, with no close frame being sent) when a status code is expected.

Unsupported_Data

1007, The endpoint is terminating the connection because a message was received that contained inconsistent data (e.g., nonUTF8 data within a text message).

Policy_Violation

1008, The endpoint is terminating the connection because it received a message that violates its policy. This is a generic status code, used when codes 1003 and 1009 are not suitable.

CLOSE_TOO_LARGE

1009, The endpoint is terminating the connection because a data frame was received that is too large.

Missing_Extension

1010, The client is terminating the connection because it expected the server to negotiate one or more extension, but the server didn't.

Internal_Error

1011, The server is terminating the connection because it encountered an unexpected condition that prevented it from fulfilling the request.

Service_Restart

1012, The server is terminating the connection because it is restarting.

Try_Again_Later

1013, The server is terminating the connection due to a temporary condition, e.g. it is overloaded and is casting off some of its clients.

TLS_Handshake

1015, Reserved. Indicates that the connection was closed due to a failure to perform a TLS handshake (e.g., the server certificate can't be verified).

OtherCode Int

OtherCode that is reserved and not in the range 0999

Instances

Instances details
Show CloseCode Source # 
Instance details

Defined in Miso.Runtime

Eq CloseCode Source # 
Instance details

Defined in Miso.Runtime

data Closed Source #

Closed message is sent when a WebSocket has closed

Constructors

Closed 

Fields

Instances

Instances details
Show Closed Source # 
Instance details

Defined in Miso.Runtime

Eq Closed Source # 
Instance details

Defined in Miso.Runtime

Methods

(==) :: Closed -> Closed -> Bool #

(/=) :: Closed -> Closed -> Bool #

FromJSVal Closed Source # 
Instance details

Defined in Miso.Runtime

data Payload value Source #

Payload is used as the potential source of data when working with EventSource

Constructors

JSON value

JSON-encoded data

BLOB Blob

Binary encoded data

TEXT MisoString

Text encoded data

BUFFER ArrayBuffer

Buffered data

newtype Blob Source #

Constructors

Blob JSVal 

Instances

Instances details
Eq Blob Source # 
Instance details

Defined in Miso.FFI.Internal

Methods

(==) :: Blob -> Blob -> Bool #

(/=) :: Blob -> Blob -> Bool #

FromJSVal Blob Source # 
Instance details

Defined in Miso.FFI.Internal

ToJSVal Blob Source # 
Instance details

Defined in Miso.FFI.Internal

Methods

toJSVal :: Blob -> IO JSVal Source #

newtype ArrayBuffer Source #

Constructors

ArrayBuffer JSVal 

Instances

Instances details
Eq ArrayBuffer Source # 
Instance details

Defined in Miso.FFI.Internal

FromJSVal ArrayBuffer Source # 
Instance details

Defined in Miso.FFI.Internal

ToJSVal ArrayBuffer Source # 
Instance details

Defined in Miso.FFI.Internal