Ethereumex.WebsocketServer (ethereumex v0.11.0)

View Source

WebSocket client implementation for Ethereum JSON-RPC API.

This module manages a persistent WebSocket connection to an Ethereum node and handles the complete request-response cycle for JSON-RPC calls. It maintains state of ongoing requests and matches responses to their original callers.

Request Lifecycle

  1. Client sends a request through post/1 with a JSON-RPC encoded payload
  2. The request is decoded and its ID is extracted (supporting both single and batch requests)
  3. A mapping is created between the request ID and the caller's PID
  4. The request is sent over the WebSocket connection
  5. The caller waits for a response (with a @request_timeout ms timeout)
  6. When a response arrives, it's matched with the original request ID
  7. The response is forwarded to the waiting caller
  8. The request is removed from the tracking map

Request State Management

The module maintains a state map of pending requests in the format:

%{
  request_id => caller_pid,
  ...
}

This allows multiple concurrent requests to be handled correctly, with responses being routed back to their original callers.

Batch Requests

For batch requests (multiple JSON-RPC calls in a single request), the request IDs are concatenated with "_" to create a unique identifier. The responses are collected and returned as a list in the same order as the original requests.

Error Handling

  • Connection failures are automatically retried with exponential backoff:
    • Up to @max_reconnect_attempts attempts
    • Starting with @backoff_initial_delay ms delay, doubling each attempt
    • Reconnection attempts are logged
  • Request timeouts after @request_timeout ms
  • Invalid JSON responses are handled gracefully
  • Unmatched responses (no waiting caller) are safely ignored

Summary

Functions

Sends a JSON-RPC request and waits for response.

Starts the WebSocket connection.

Types

request_id()

@type request_id() :: pos_integer() | String.t()

Functions

post(encoded_request)

@spec post(binary()) ::
  {:ok, term()} | {:error, :invalid_request_format | :timeout | :decoded_error}

Sends a JSON-RPC request and waits for response.

Returns {:ok, result} on success or {:error, reason} on failure. Times out after 5000ms.

start_link(opts \\ [])

@spec start_link(keyword()) :: {:ok, pid()} | {:error, term()}

Starts the WebSocket connection.

Options

  • :url - WebSocket endpoint URL (defaults to Config.websocket_url())
  • :name - Process name (defaults to MODULE)