Parley
WebSocket client for Elixir built on gen_statem and Mint WebSocket.
Full documentation on HexDocs.
Installation
Add parley to your list of dependencies in mix.exs:
def deps do
[
{:parley, "~> 0.2.0"}
]
endUsage
Define a client module with use Parley and implement the callbacks you need:
defmodule MyClient do
use Parley
@impl true
def handle_connect(state) do
IO.puts("Connected!")
{:ok, state}
end
@impl true
def handle_frame({:text, msg}, state) do
IO.puts("Received: #{msg}")
{:ok, state}
end
@impl true
def handle_disconnect(reason, state) do
IO.puts("Disconnected: #{inspect(reason)}")
{:ok, state}
end
endThen start the client and send frames:
{:ok, pid} = MyClient.start_link(%{}, url: "wss://example.com/ws")
Parley.send_frame(pid, {:text, "hello"})
Parley.disconnect(pid)Options
start_link/2 accepts the following options:
:url(required) — the WebSocket URL to connect to (ws://orwss://):name— an optional name for the process (passed to:gen_statem):headers— custom headers sent with the WebSocket upgrade request (e.g.[{"authorization", "Bearer token"}]):connect_timeout— timeout in milliseconds for the WebSocket upgrade handshake (default:10_000):transport_opts— options passed to the transport layer (:gen_tcpforws://,:sslforwss://):protocols— Mint HTTP protocols to use for the connection (default:[:http1])
The first argument is the initial state passed to init/1.
Callbacks
All callbacks are optional — default implementations are provided via use Parley.
| Callback | Description | Return values |
|---|---|---|
init(init_arg) | Called when the process starts, before connecting | {:ok, state}, {:stop, reason} |
handle_connect(state) | Called when the WebSocket handshake completes | {:ok, state}, {:push, frame, state}, {:stop, reason, state} |
handle_frame(frame, state) | Called when a frame is received from the server | {:ok, state}, {:push, frame, state}, {:stop, reason, state} |
handle_ping(payload, state) | Called when a ping is received (pong sent automatically) | {:ok, state}, {:push, frame, state}, {:stop, reason, state} |
handle_info(message, state) | Called when a non-WebSocket message is received | {:ok, state}, {:push, frame, state}, {:stop, reason, state} |
handle_disconnect(reason, state) | Called when the connection is lost or closed | {:ok, state} |
{:ok, state}— update state{:push, frame, state}— send a frame from within the callback{:stop, reason, state}— stop the process
Frame Types
Frames are tuples matching the type {:text, String.t()} | {:binary, binary()} | {:ping, binary()} | {:pong, binary()}.
Ping frames from the server are automatically answered with pong — no user code needed.
Sends During Connection
Frames sent while the WebSocket handshake is still in progress are automatically queued and delivered once the connection is established.