March Docs

WebSocket

WebSocket module: types and API for WebSocket connections.

WebSocket connections are upgraded from HTTP via WebSocket.upgrade(conn, handler). The handler is a function WsSocket -> Unit that uses tail recursion and pattern matching on received frames.

Types

typeWsFrameWsFrame = TextFrame(String) | BinaryFrame(String) | Ping | Pong | Close(Int, String)#
typeWsSocketWsSocket = WsSocket(Int)#
typeSelectResultSelectResult = WsData(WsFrame) | ActorMsg | Timeout#

Functions

fncloseclose(socket, code, reason)#

Send a Close(code, reason) frame (e.g. 1000 for a normal closure). The handler should then return; the runtime closes the TCP connection.

Examples

WebSocket.close(socket, 1000, "bye")
fnrecvrecv(socket)#

Receive the next frame, parking the calling task until one arrives. Returns TextFrame(s), BinaryFrame(s), Ping, Pong or Close(code, reason). A read error or peer disconnect yields Close(1001, "going away"); a frame over 16 MiB likewise; an unknown opcode (including continuation frames of a fragmented message) yields Close(1002, "unknown opcode"). Pings are not answered automatically.

Examples

fn echo_loop(socket) do
  match WebSocket.recv(socket) do
    TextFrame(s) ->
      WebSocket.send_frame(socket, TextFrame(s))
      echo_loop(socket)
    Ping ->
      WebSocket.send_frame(socket, Pong)
      echo_loop(socket)
    Close(_, _) -> ()
    _ -> echo_loop(socket)
  end
end
fnselectselect(socket, timeout_ms)#

Wait up to timeout_ms milliseconds for a frame. Returns WsData(frame) (the frame as recv would give it) or Timeout; a timeout_ms of 0 or less waits indefinitely. A wait error is reported as Timeout.

ActorMsg is part of the result type, but this function passes no actor notification pipe to the runtime, so it is never returned here.

Examples

match WebSocket.select(socket, 30000) do
  WsData(TextFrame(s)) -> handle(s)
  WsData(_) -> ()
  _ -> WebSocket.send_frame(socket, Ping)
end
fnsend_framesend_frame(socket, frame)#

Send one frame (server to client, unmasked) on the socket. Returns ().

Examples

WebSocket.send_frame(socket, TextFrame("hello"))
fnupgradeupgrade(conn, handler)#

Mark an HttpServer.Conn for upgrade to a WebSocket. Returns the conn with status 101, response headers and body cleared, halted, and WebSocketUpgrade(handler) set; after the pipeline returns, the server runtime performs the handshake and calls handler(socket).

This function does not itself check the request's Upgrade / Sec-WebSocket-Key headers, nor whether the conn was already halted (an earlier response is overwritten); do that in the plug first.

Examples

fn ws_plug(conn) do
  if HttpServer.path(conn) == "/ws" do
    WebSocket.upgrade(conn, echo_loop)
  else
    conn
  end
end