WebsockexNova

View Source

A robust, highly extensible WebSocket client library for Elixir with elegant abstractions for building specialized WebSocket clients.

This library is based on the excellent Websockex library by Azolo and has been heavily extended with additional capabilities including behavior-based extensibility, adapter patterns, Gun transport integration, automatic reconnection, subscription management, rate limiting, and more.

Features

  • Behavior-Based Architecture: Easily extendable through behavior interfaces
  • Adapter Pattern: Customize specific aspects of WebSocket communication
  • Default Implementations: Sensible defaults provided for all behaviors
  • Gun Integration: Uses the battle-tested Gun library as the transport layer
  • Client Macro: Simplify creation of service-specific WebSocket clients
  • Adapter Macro: Build service-specific adapters with minimal boilerplate
  • Rate Limiting: Built-in rate limiting capabilities
  • Observability: Rich telemetry and logging support

Installation

Add websockex_nova to your list of dependencies in mix.exs:

def deps do
  [
    {:websockex_nova, "~> 0.1.0"}
  ]
end

Usage

Basic Usage

# Connect to a WebSocket server
{:ok, conn} = WebsockexNova.Client.connect(WebsockexNova.Defaults.DefaultAdapter, %{
  host: "echo.websocket.org",
  port: 443,
  path: "/",
  transport: :tls
})

# Send a message
{:ok, response} = WebsockexNova.Client.send_text(conn, "Hello, WebSocket!")

# Close the connection
WebsockexNova.Client.close(conn)

Using ClientMacro

Create service-specific clients with minimal boilerplate using WebsockexNova.ClientMacro:

defmodule MyApp.DeribitClient do
  use WebsockexNova.ClientMacro, adapter: MyApp.DeribitAdapter

  # Add domain-specific methods:
  def subscribe_to_trades(conn, instrument, opts \\ nil) do
    channel = "trades.#{instrument}.raw"
    subscribe(conn, channel, opts)
  end

  def subscribe_to_ticker(conn, instrument, opts \\ nil) do
    channel = "ticker.#{instrument}.raw"
    subscribe(conn, channel, opts)
  end
end

# Usage
{:ok, conn} = MyApp.DeribitClient.connect()
{:ok, _} = MyApp.DeribitClient.subscribe_to_trades(conn, "BTC-PERPETUAL")

Using AdapterMacro

Create service-specific adapters with minimal boilerplate using WebsockexNova.Adapter:

defmodule MyApp.DeribitAdapter do
  use WebsockexNova.Adapter

  # Override only what you need:
  @impl WebsockexNova.Behaviors.ConnectionHandler
  def connection_info(opts) do
    defaults = %{
      host: "www.deribit.com",
      port: 443,
      path: "/ws/api/v2",
      transport: :tls
    }

    {:ok, Map.merge(defaults, opts)}
  end

  @impl WebsockexNova.Behaviors.MessageHandler
  def handle_message(message, state) do
    # Custom message handling...
    {:ok, decoded_message, updated_state}
  end
end

Documentation

Comprehensive documentation is available in the docs/ directory:

  • Architecture Overview: docs/architecture.md
  • Client Macro Guide: docs/client_macro.md
  • Implementation Plan: docs/plan.md

License

This project is licensed under the MIT License - see the LICENSE file for details.