Browser-like WebSocket client API for Elixir.
Events are delivered as messages to the owner process:
{HTTP.WebSocket, socket, %HTTP.WebSocket.Event.Open{}}
{HTTP.WebSocket, socket, %HTTP.WebSocket.Event.Message{}}
{HTTP.WebSocket, socket, %HTTP.WebSocket.Event.Error{}}
{HTTP.WebSocket, socket, %HTTP.WebSocket.Event.Close{}}HTTP/1 is the default. Select http_version: :http2, :h2c, or :auto
explicitly; http_version/1 reports the negotiated HTTP version, while
protocol/1 continues to report the selected WebSocket subprotocol.
With delivery: :ack, message events include a delivery reference:
{HTTP.WebSocket, socket, %HTTP.WebSocket.Event.Message{}, ref}Call acknowledge/2 after consuming each message. Open, Error, and Close
retain their three-element event envelopes. Receive queues, pending sends,
and fragmented messages have finite configurable limits. Established sessions
default to idle_timeout: :infinity; opening and close deadlines are separate.
Telemetry URLs omit query, userinfo, authority, and fragment by default.
Pass telemetry_url: nil to omit all URL-derived telemetry metadata, or a
URI/string containing only caller-approved fields to replace the telemetry
URL (for example, telemetry_url: "ws://127.0.0.1:8080" omits a private
path). Invalid replacements reject construction; replacement credentials
are always stripped. This option applies to every lifecycle/message event
and never changes the transport URL or handshake.
HTTP/1 WebSocket proxy boundary
For frame forwarding, select mode: :proxy, http_version: :http1,
delivery: :ack and automatic_pong: false. Proxy mode delivers
%HTTP.WebSocket.Event.Frame{opcode: opcode, data: binary} for text, binary,
ping and pong, with the same delivery reference/acknowledge/2 contract.
binary_type does not alter proxy frame data. Close retains its lifecycle
event and automatic reply. send_frame/2 and send_frame_ack/2 accept
{opcode, binary} for those four opcodes. Automatic pong defaults to true;
disabling it requires proxy mode. Proxy close/3 accepts nil with an empty
reason, 1000-1014 except 1004/1005/1006, and 3000-4999. Reserved/non-wire
codes, invalid UTF-8 and reasons over 123 bytes remain rejected.
Proxy HTTP/2, h2c and auto selection return {:error, :proxy_requires_http1}.
Wait for successful completion of every send_frame_ack/2 reference
before initiating Close: local close discards queued application frames in
both HTTP versions. This provides ordered local write completion over HTTP/1;
proxy mode supplies no HTTP/2 drain contract. Control sends share the bounded
application send FIFO, including zero-length payloads. Control delivery uses
the receive limits too; ACK capacity must accommodate at least 132 bytes.
Use this public client for the upstream half of a WebSocket proxy. Select
http_version: :http1 and delivery: :ack; acknowledge each Message only
after downstream consumption. Set finite opening_timeout, idle_timeout,
write_timeout and close_timeout, and size/count limits for messages,
receive queues and pending sends. send_ack/2 reports local transport
completion for each admitted frame. send/2 reports admission only.
The client validates status 101, Upgrade/Connection tokens, exactly one
matching Sec-WebSocket-Accept and the selected subprotocol. Bytes coalesced
after the response head enter the frame parser. Redirects and uncertain
operations are never replayed. Ping is answered with Pong automatically;
Close is exchanged with the peer. This interface proxies WebSocket messages,
not raw TCP bytes or exact frame fragmentation. Forward binary messages
with array_buffer/1 and configure the upstream protocols explicitly.
WSS retains the selected TLS backend's CA, hostname and SNI verification;
supply trusted ssl: [cacertfile: ...] for private CAs. Owner death closes
the connection. close/1 signals cancellation; monitor the socket's public
pid for :DOWN to confirm cleanup, including a cancelled opening. A
Close event describes the handshake result; it does not prove peer
application receipt of earlier writes. Terminal cancellation discards
pending transport bytes, so a failed write may have reached the peer partly.
Plain Elixir binaries are sent as text frames. Use array_buffer/1 or
HTTP.Blob for binary frames.
For wss connections, pass tls_backend: :ssl | :ex_ssl (or the equivalent
string in a map). When omitted, the shared :http_core TLS backend setting is
captured when the socket is created.
Summary
Functions
Acknowledges an ACK-mode message delivery reference.
Returns the negotiated HTTP version, or nil before establishment.
Admits a bounded send and returns its completion reference.
Admits an explicit text, binary, ping or pong frame in mode: :proxy.
Admits an explicit proxy frame and returns a local write completion reference.
Returns connection state and bounded delivery and send queue usage.
Types
Functions
Acknowledges an ACK-mode message delivery reference.
@spec array_buffer(binary()) :: HTTP.WebSocket.ArrayBuffer.t() | {:error, :invalid_array_buffer}
@spec binary_type(t()) :: :blob | :array_buffer
@spec buffered_amount(t()) :: non_neg_integer()
@spec close(t(), non_neg_integer()) :: :ok | {:error, term()}
@spec close(t(), non_neg_integer() | nil, String.t()) :: :ok | {:error, term()}
@spec closed() :: 3
@spec closing() :: 2
@spec connecting() :: 0
@spec http_version(t()) :: :http1 | :http2 | nil
Returns the negotiated HTTP version, or nil before establishment.
@spec open() :: 1
@spec ready_state(t()) :: 0 | 1 | 2 | 3
@spec send(t(), String.t() | HTTP.Blob.t() | HTTP.WebSocket.ArrayBuffer.t()) :: :ok | {:error, term()}
@spec send_ack(t(), String.t() | HTTP.Blob.t() | HTTP.WebSocket.ArrayBuffer.t()) :: {:ok, reference()} | {:error, term()}
Admits a bounded send and returns its completion reference.
The owner receives {HTTP.WebSocket, socket, {:send_result, ref, result}},
where result is :ok only after the complete frame was accepted by the
transport, or {:error, reason} on cancellation/failure. This confirms local
write completion, not peer application receipt. Failed/uncertain writes are
never replayed. Unlike send/2, a closed connection rejects admission.
Queuing and writing share the finite write_timeout (default 5 seconds).
Admits an explicit text, binary, ping or pong frame in mode: :proxy.
Control payloads are limited to 125 bytes; text must be valid UTF-8. Frames
share the bounded FIFO send queue and write deadline with send/2. This
reports admission only; use send_frame_ack/2 before forwarding Close.
Send Close using close/3, preserving the connection's close deadline.
@spec send_frame_ack(t(), {:text | :binary | :ping | :pong, binary()}) :: {:ok, reference()} | {:error, term()}
Admits an explicit proxy frame and returns a local write completion reference.
The owner receives the same {:send_result, ref, result} event as send_ack/2.
Wait for :ok for every admitted frame before calling close/3 to preserve
prior writes. Completion does not prove peer application receipt.
Returns connection state and bounded delivery and send queue usage.