Mint.WebSocket - (unofficial) WebSocket support for Mint 🌱

Mint.WebSocket (github) (hex) is a library built on the awesome Mint (github) (hex) functional HTTP client.

Mint.WebSocket extends Mint’s process-less architecture with a handful of functions for upgrading connections to the WebSocket protocol and encoding and decoding WebSocket frames. For example, we can send and receive some frames from an echo WebSocket server:

# see https://websocket.org/echo.html
{:ok, conn} = Mint.HTTP.connect(:https, "echo.websocket.org", 443)

{:ok, conn, ref} = Mint.WebSocket.upgrade(conn, "/", [])

message = receive(do: (message -> message))
{:ok, conn, [{:status, ^ref, status}, {:headers, ^ref, resp_headers}, {:done, ^ref}]} =
  Mint.HTTP.stream(conn, message)
{:ok, conn, websocket} = Mint.WebSocket.new(conn, ref, status, resp_headers)

{:ok, websocket, data} =
  Mint.WebSocket.encode(websocket, {:text, "Rock it with Mint.WebSocket"})
{:ok, conn} = Mint.HTTP.stream_request_body(conn, ref, data)

message = receive(do: (message -> message))
{:ok, conn, [{:data, ^ref, data}]} = Mint.HTTP.stream(conn, message)
{:ok, websocket, [{:text, "Rock it with Mint.WebSocket"}]} =
  Mint.WebSocket.decode(websocket, data)

{:ok, websocket, data} = Mint.WebSocket.encode(websocket, :close)
{:ok, conn} = Mint.HTTP.stream_request_body(conn, ref, data)

message = receive(do: (message -> message))
{:ok, conn, [{:data, ^ref, data}]} = Mint.HTTP.stream(conn, message)
{:ok, websocket, [{:close, 1_000, ""}]} =
  Mint.WebSocket.decode(websocket, data)

Mint.HTTP.close(conn)

Features:

  • HTTP/1 and HTTP/2 support through the same API
    • although HTTP/2 WebSocket support is currently very limited among server frameworks
  • support for Extensions
    • the popular “permessage-deflate” extension is included in the library
  • conformance checks with the Autobahn|Testsuite are built in to the CI
  • performance is roughly on par with :gun (Autobahn|Testsuite comparison)
17 Likes