WebSocket Event Subscription

Overview

The **WebSocket Event Subscription** module provides real-time subscription management for blockchain events by leveraging WebSocket client connections, a subscription registry, and event dispatching mechanisms. Its primary purpose is to enable clients to subscribe to blockchain transaction events related to specific addresses and receive immediate updates without polling.

This module solves the problem of efficiently managing multiple client subscriptions over WebSocket connections while disseminating relevant blockchain transaction data only to interested subscribers. It abstracts the complexity of handling WebSocket connections, subscription lifecycles, and event broadcasting, ensuring scalable and responsive real-time data delivery.


Core Concepts and Purpose


Key Functionalities and Workflow

1. WebSocket Connection Lifecycle and Message Handling

Each incoming WebSocket connection from a client is wrapped within a `ConnectionHandler` instance. This handler manages the connection's lifecycle, including:

Example snippet illustrating subscription routing:

this.routes = {
  txs: {
    subscribe: (subscriptionId, data) => this.handleSubscribeTxs(subscriptionId, data),
    unsubscribe: (subscriptionId, data) => this.handleUnsubscribeTxs(subscriptionId, data),
  },
}

2. Subscription Registration and Deregistration

When a client subscribes to transaction events for specific addresses, the `ConnectionHandler` adds the subscription to its internal set and delegates the registration to the centralized `Registry`. Similarly, unsubscription requests remove the subscription and update the registry.

This ensures:

Snippet illustrating subscription registration:

this.subscriptionIds.add(subscriptionId)
this.registry.subscribe(this.clientId, subscriptionId, this, data.addresses)
this.client.subscribeAddresses(this.registry.getAddresses())

3. Centralized Subscription Registry

The `Registry` class acts as the core data structure managing all active subscriptions:

This dual mapping allows:

Example data structures:

private clients: Record<string, Set<string>> = {}
private addresses: Record<string, Map<string, ConnectionHandler>> = {}

4. Event Handling and Broadcasting

When new blockchain blocks or transactions are received (from upstream WebSocket clients connected to blockchain indexers), the `Registry` processes these events:

Example publishing logic:

private publishTransaction(addresses: string[], tx: unknown) {
  addresses.forEach((address) => {
    if (!this.addresses[address]) return

    for (const [id, connection] of this.addresses[address].entries()) {
      const { subscriptionId } = Registry.fromId(id)
      connection.publish(subscriptionId, address, tx)
    }
  })
}

Interactions with Other System Components


Design Patterns and Approaches


Code References Summary


Mermaid Sequence Diagram: WebSocket Event Subscription Flow

sequenceDiagram
  participant Client as WebSocket Client
  participant Conn as ConnectionHandler
  participant Reg as Registry
  participant Indexer as Blockchain Indexer WS Client

  Client->>Conn: Send {"method":"subscribe","subscriptionId":"sub1","data":{"topic":"txs","addresses":["addr1"]}}
  Conn->>Reg: subscribe(clientId, "sub1", Conn, ["addr1"])
  Reg-->>Conn: (updates internal maps)
  Conn->>Indexer: subscribeAddresses(registry.getAddresses())

  Indexer->>Reg: New Transaction Event (tx involving addr1)
  Reg->>Reg: Extract addresses from tx
  Reg->>Conn: publish("sub1", "addr1", tx)
  Conn->>Client: Send tx event message

  Client->>Conn: Send {"method":"unsubscribe","subscriptionId":"sub1","data":{"topic":"txs","addresses":["addr1"]}}
  Conn->>Reg: unsubscribe(clientId, "sub1", ["addr1"])
  Reg-->>Conn: (updates internal maps)
  Conn->>Indexer: subscribeAddresses(registry.getAddresses())

  Client->>Conn: Disconnect
  Conn->>Reg: unsubscribe all subscriptions for clientId
  Reg-->>Conn: (cleans up)

This documentation captures the core purpose, architecture, and workflow of the WebSocket Event Subscription module, highlighting its role in providing scalable, real-time blockchain event delivery to subscribed clients.