WebsockexNova.Gun.FrameCodec (WebsockexNova v0.1.1)
View SourceHandles encoding and decoding of WebSocket frames.
This module provides functionality for working with WebSocket frames in Gun. It handles various frame types (text, binary, ping, pong, close) and provides utilities for validating frames and working with close codes.
The module uses a pluggable handler system that allows for custom frame handlers to be registered, supporting extensions like permessage-deflate and other WebSocket extensions.
Gun WebSocket frames are represented as:
{:text, binary()}
- Text frames{:binary, binary()}
- Binary frames:ping
or{:ping, binary()}
- Ping frames:pong
or{:pong, binary()}
- Pong frames:close
or{:close, code()}
or{:close, code(), binary()}
- Close frames
Summary
Functions
Returns the meaning of a WebSocket close code.
Decodes a WebSocket frame received from Gun.
Encodes a WebSocket frame for sending via Gun.
Gets the handler module for a specific frame type.
Determines the frame type of a WebSocket frame.
Initializes the ETS table for frame handlers.
Registers a custom frame handler for a specific frame type.
Checks if a WebSocket close code is valid.
Validates a WebSocket close code.
Validates the size of a control frame payload.
Validates a WebSocket frame.
Types
@type frame() :: {:text, binary()} | {:binary, binary()} | :ping | {:ping, binary()} | :pong | {:pong, binary()} | :close | {:close, non_neg_integer()} | {:close, non_neg_integer(), binary()}
@type validate_result() :: :ok | {:error, atom()}
Functions
@spec close_code_meaning(non_neg_integer()) :: String.t()
Returns the meaning of a WebSocket close code.
Examples
iex> WebsockexNova.Gun.FrameCodec.close_code_meaning(1000)
"Normal closure"
iex> WebsockexNova.Gun.FrameCodec.close_code_meaning(3000)
"Unknown close code"
@spec decode_frame(tuple() | atom()) :: decode_result()
Decodes a WebSocket frame received from Gun.
Takes a frame in the Gun format and converts it to the internal format. Uses the appropriate frame handler based on the frame type.
Examples
iex> WebsockexNova.Gun.FrameCodec.decode_frame({:text, "Hello"})
{:ok, {:text, "Hello"}}
iex> WebsockexNova.Gun.FrameCodec.decode_frame(:ping)
{:ok, :ping}
iex> WebsockexNova.Gun.FrameCodec.decode_frame({:close, 1000, "Normal closure"})
{:ok, {:close, 1000, "Normal closure"}}
Encodes a WebSocket frame for sending via Gun.
Takes a frame in the internal format and converts it to the format expected by Gun. Uses the appropriate frame handler based on the frame type.
Examples
iex> WebsockexNova.Gun.FrameCodec.encode_frame({:text, "Hello"})
{:text, "Hello"}
iex> WebsockexNova.Gun.FrameCodec.encode_frame(:ping)
:ping
iex> WebsockexNova.Gun.FrameCodec.encode_frame({:close, 1000, "Normal closure"})
{:close, 1000, "Normal closure"}
Gets the handler module for a specific frame type.
Uses the built-in handler registry, which can be extended at runtime
with register_frame_handler/2
.
Parameters
frame_type
- The type of frame to get a handler for
Returns
The handler module for the specified frame type
Determines the frame type of a WebSocket frame.
Parameters
frame
- The WebSocket frame
Returns
The frame type as an atom (:text
, :binary
, etc.)
@spec init_handlers_table() :: :ok | {:error, :table_exists}
Initializes the ETS table for frame handlers.
This function creates the ETS table for storing frame handlers if it doesn't exist yet. It is called once at application startup to ensure the table exists before it's accessed.
Returns
:ok
- When the table is successfully initialized{:error, :table_exists}
- When the table already exists
Registers a custom frame handler for a specific frame type.
This allows for extending the WebSocket frame handling with custom implementations, such as for handling extensions.
Parameters
frame_type
- The type of frame to register a handler forhandler_module
- The module that implements the handler behavior
Returns
:ok
- If the handler was registered successfully{:error, :table_missing}
- If the handler registry table doesn't exist
@spec valid_close_code?(non_neg_integer()) :: boolean()
Checks if a WebSocket close code is valid.
Examples
iex> WebsockexNova.Gun.FrameCodec.valid_close_code?(1000)
true
iex> WebsockexNova.Gun.FrameCodec.valid_close_code?(999)
false
@spec validate_close_code(non_neg_integer()) :: validate_result()
Validates a WebSocket close code.
Examples
iex> WebsockexNova.Gun.FrameCodec.validate_close_code(1000)
:ok
iex> WebsockexNova.Gun.FrameCodec.validate_close_code(999)
{:error, :invalid_close_code}
iex> WebsockexNova.Gun.FrameCodec.validate_close_code(1005)
{:error, :reserved_close_code}
@spec validate_control_frame_size(binary()) :: validate_result()
Validates the size of a control frame payload.
WebSocket protocol limits control frame payloads to 125 bytes.
Parameters
data
- Binary payload data to validate
Returns
:ok
- If the payload size is valid{:error, :control_frame_too_large}
- If payload exceeds 125 bytes
@spec validate_frame(frame()) :: validate_result()
Validates a WebSocket frame.
Checks if a frame is valid according to the WebSocket spec. Uses the appropriate frame handler based on the frame type.
Examples
iex> WebsockexNova.Gun.FrameCodec.validate_frame({:text, "Hello"})
:ok
iex> WebsockexNova.Gun.FrameCodec.validate_frame({:text, nil})
{:error, :invalid_text_data}
iex> WebsockexNova.Gun.FrameCodec.validate_frame({:close, 1000})
:ok