websocket.ts

Overview

`websocket.ts` provides an abstract foundation for implementing resilient WebSocket clients. It defines the `WebsocketClient` abstract class, which manages WebSocket connection lifecycle, including automatic reconnection, heartbeat monitoring via ping/pong frames, and connection resets. The class is designed to be extended by concrete implementations that specify how to handle incoming messages and subscribe to data streams.

This file also exports interfaces to define subscription messages and configuration options, allowing flexible customization of client behavior. The primary goal is to provide a robust, reusable WebSocket client base that handles common networking concerns transparently, enabling subclasses to focus on application-specific processing.


Interfaces

Subscription

Represents a JSON-RPC 2.0 subscription message to be sent over the WebSocket.

Property

Type

Description

jsonrpc

`'2.0'`

JSON-RPC protocol version (fixed)

id

`string`

Unique identifier for the request

method

`string`

The RPC method name

params

`unknown` (optional)

Optional parameters for the method

**Usage Example:**

const sub: Subscription = {
  jsonrpc: '2.0',
  id: '1',
  method: 'subscribe',
  params: { channel: 'orders' }
}

Args

Configuration parameters required when constructing a `WebsocketClient`.

Property

Type

Description

apiKey

`string` (optional)

API key for authentication

logger

`Logger`

Logger instance for logging


Options

Optional parameters to fine-tune WebSocket client behavior.

Property

Type

Default

Description

pingInterval

`number`

`10000` ms

Interval between sending ping frames to keep connection alive

retryAttempts

`number`

`0` (infinite retries)

Maximum reconnection attempts before throwing error

resetInterval

`number`

`30000` ms

Time interval after which the connection is reset


Class: WebsocketClient

Abstract base class for a WebSocket client that manages connection lifecycle, retries, heartbeat, and message handling.

Properties

Name

Type

Description

`socket`

`WebSocket`

The current WebSocket connection instance

`url`

`string`

URL of the WebSocket server

`pingTimeout`

`NodeJS.Timeout \

undefined`

`interval`

`NodeJS.Timeout \

undefined`

`resetTimeout`

`NodeJS.Timeout \

undefined`

`retryCount`

`number`

Number of reconnection attempts so far

`logger`

`Logger`

Logger instance for debug and error messages

`pingInterval`

`number`

Interval between ping frames

`retryAttempts`

`number`

Max reconnection attempts

`resetInterval`

`number`

Interval after which the connection is reset

Constructor

constructor(url: string, args: Args, opts?: Options)

Initializes the WebSocket connection and sets configuration parameters.


Abstract Methods

Subclasses must implement these methods to provide custom connection logic.

onOpen(): void

Called once the WebSocket connection is opened and ready.

onMessage(message: WebSocket.MessageEvent): Promise<void>

Handles incoming messages from the WebSocket.

subscribeAddresses(addresses: string[]): void

Abstract method to subscribe to updates for a list of blockchain addresses or similar entities.


Protected Methods

initialize(): void

Sets up event handlers for the WebSocket connection:

Called internally when a new WebSocket connection is created.

reset(): void

Schedules a connection reset after `resetInterval` milliseconds by terminating the socket, which triggers a reconnect.

If `resetInterval` is 0, disables automatic reset.


Private Methods

close(): void

Handles connection closure and reconnection logic:

heartbeat(): void

Sets a timeout waiting for a `pong` response to the last ping. If the timeout fires, it terminates the socket connection indicating a failed heartbeat.


Implementation Details


Interaction with Other System Components


Usage Example (Subclass Skeleton)

import { WebsocketClient, Args } from './websocket'

class MyWebsocketClient extends WebsocketClient {
  protected onOpen(): void {
    this.logger.info('Connection established')
    this.subscribeAddresses(['addr1', 'addr2'])
  }

  protected async onMessage(message: WebSocket.MessageEvent): Promise<void> {
    const data = JSON.parse(message.data.toString())
    this.logger.debug({ data }, 'Received message')
    // process data here
  }

  subscribeAddresses(addresses: string[]): void {
    const subscription = {
      jsonrpc: '2.0',
      id: '1',
      method: 'subscribe',
      params: { addresses }
    }
    this.socket.send(JSON.stringify(subscription))
  }
}

const client = new MyWebsocketClient('wss://example.com/ws', { logger })
client.initialize()

Mermaid Class Diagram

classDiagram
    class WebsocketClient {
        -socket: WebSocket
        -url: string
        -pingTimeout: NodeJS.Timeout
        -interval: NodeJS.Timeout
        -resetTimeout: NodeJS.Timeout
        -retryCount: number
        -logger: Logger
        -pingInterval: number
        -retryAttempts: number
        -resetInterval: number

        +constructor(url: string, args: Args, opts?: Options)
        +initialize(): void
        +reset(): void

        #onOpen(): void
        #onMessage(message: WebSocket.MessageEvent): Promise~void~
        +subscribeAddresses(addresses: string[]): void

        -close(): void
        -heartbeat(): void
    }

This documentation covers the design and usage of `websocket.ts`, enabling developers to extend or utilize `WebsocketClient` for robust WebSocket communication in their applications.