websocket-ts

repository·main·Indexed 41 days ago

https://github.com/jjxxs/websocket-ts

A lightweight TypeScript WebSocket client library for browsers featuring automatic reconnection, message buffering, and dynamic URL providers. Version 2.3.0 includes a fluent WebsocketBuilder and multiple backoff strategies (Constant, Linear, and Exponential) to manage reconnection timing, as well as RingQueue and ArrayQueue implementations for preventing message loss during disconnections.

Tokens
7.7K
Snippets
28
Records
39
Agent score
99%

What's inside websocket-ts

  1. Quickstart: WebSocket with buffering and auto-reconnect

    main

    This example demonstrates how to initialize a WebSocket using WebsocketBuilder with an ArrayQueue for message buffering and a ConstantBackoff strategy for reconnection attempts every 1 second. It also shows how to add event listeners using addEventListener to echo received messages.

    import {
      ArrayQueue,
      ConstantBackoff,
      Websocket,
      WebsocketBuilder,
      WebsocketEvent,
    } from "websocket-ts";
    
    // Initialize WebSocket with buffering and 1s reconnection delay
    const ws = new WebsocketBuilder("ws://localhost:8080")
      .withBuffer(new ArrayQueue())           // buffer messages when disconnected
      .withBackoff(new ConstantBackoff(1000)) // retry every 1s
      .build();
    
    // Function to output & echo received messages
    const echoOnMessage = (i: Websocket, ev: MessageEvent) => {
      console.log(`received message: ${ev.data}`);
      i.send(`echo: ${ev.data}`);
    };
    
    // Add event listeners
    ws.addEventListener(WebsocketEvent.open, () => console.log("opened!"));
    ws.addEventListener(WebsocketEvent.close, () => console.log("closed!"));
    ws.addEventListener(WebsocketEvent.message, echoOnMessage);
  2. How automatic reconnection and buffering work together

    main

    The Websocket class is designed to handle intermittent connectivity through two main mechanisms:

    1. Automatic Reconnection: If a connection is lost (and not closed by the user), the class uses a Backoff strategy to attempt retries. You can configure maxRetries, instantReconnect, and the backoff algorithm in the retry options.
    2. Message Buffering: If you provide a buffer in the WebsocketOptions, the class maintains a queue of messages. When a retry succeeds and the open event fires, the class automatically drains the buffer by calling .send() for every queued item.

    Mental Model: Think of the Websocket instance as a persistent pipe. You call .send() as if the connection were always up; the class manages the complexity of waiting for the connection to return and flushing your pending data.

  3. Remove WebSocket event listeners

    main

    To unregister a specific event listener, use the removeEventListener method on the Websocket instance.

    let ws: Websocket
    /* ... */
    ws.removeEventListener(WebsocketEvent.open, openEventListener);
  4. Use a dynamic URL provider

    main

    Instead of a static string, you can provide a function to the WebsocketBuilder constructor. This function is called on every connection attempt (initial and retries), allowing for dynamic URL generation such as rotating auth tokens or load balancing.

    const ws = new WebsocketBuilder(() => `ws://localhost:42421?token=${getToken()}`)
      .withBackoff(new ConstantBackoff(1000))
      .build();
  5. Handle WebSocket events

    main

    You can listen for six types of events. You can use the WebsocketEvent enum or the corresponding string literal (e.g., WebsocketEvent.open or "open"). Event listeners receive the websocket instance (i) and the triggering event (ev) as arguments.

    EventDescription
    openConnection opened
    closeConnection closed
    errorAn error occurred
    messageMessage received
    retryReconnect attempt
    reconnectSuccessful reconnect

    You can register listeners using addEventListener or the builder's convenience methods like .onOpen(), .onClose(), etc.

    const ws = new WebsocketBuilder("ws://localhost:42421")
      .onOpen((i, ev) => console.log("opened"))
      .onClose((i, ev) => console.log("closed"))
      .onError((i, ev) => console.log("error"))
      .onMessage((i, ev) => console.log("message"))
      .onRetry((i, ev) => console.log("retry"))
      .onReconnect((i, ev) => console.log("reconnect"))
      .build();
  6. Initialize a WebSocket using WebsocketBuilder

    main

    The WebsocketBuilder is the recommended way to create a new Websocket instance. By default, it uses a static URL string.

    const ws = new WebsocketBuilder("ws://localhost:42421").build();
  7. Buffer outgoing messages with a Queue

    main

    To prevent message loss during disconnection, provide a Queue implementation to the WebsocketBuilder using .withBuffer(). Messages will be stored in the queue and sent in order once the connection is re-established.

    RingQueue

    A fixed-capacity, FIFO queue. When capacity is reached, the oldest element is removed.

    const ws = new WebsocketBuilder("ws://localhost:42421")
      .withBuffer(new RingQueue(100))
      .build();

    ArrayQueue

    An unbounded FIFO queue.

    const ws = new WebsocketBuilder("ws://localhost:42421")
      .withBuffer(new ArrayQueue())
      .build();
  8. Configure reconnection strategies with Backoff

    main

    To enable automatic reconnection, provide a Backoff strategy to the WebsocketBuilder using .withBackoff(). If no backoff is provided, the websocket will not attempt to reconnect.

    ConstantBackoff

    Uses a fixed delay between each reconnection attempt.

    const ws = new WebsocketBuilder("ws://localhost:42421")
      .withBackoff(new ConstantBackoff(1000)) // 1000ms = 1s
      .build();

    LinearBackoff

    Increases the delay linearly up to an optional maximum.

    const ws = new WebsocketBuilder("ws://localhost:42421")
      .withBackoff(new LinearBackoff(0, 10000, 60000)) // 0ms, 10s, 20s, 30s, 40s, 50s, 60s
      .build();

    ExponentialBackoff

    Doubles the delay between each reconnection attempt up to a specified maximum.

    const ws = new WebsocketBuilder("ws://localhost:42421")
      .withBackoff(new ExponentialBackoff(1000, 6)) // 1s, 2s, 4s, 8s, 16s, 32s, 64s
      .build();
  9. Configure WebsocketOptions for the Websocket constructor

    main

    When instantiating a Websocket client, you can provide a WebsocketOptions object to customize its behavior. The available configuration keys are:

    • buffer: An optional WebsocketBuffer instance to manage data buffering.
    • retry: An optional WebsocketConnectionRetryOptions object to define the connection-retry-strategy.
    • listeners: An optional WebsocketEventListeners object to register initial event handlers for the websocket.
    const options: WebsocketOptions = {
      buffer: myBuffer,
      retry: myRetryOptions,
      listeners: myEventListeners
    };
    
    const ws = new Websocket(url, options);
  10. Configure WebsocketConnectionRetryOptions

    main

    The WebsocketConnectionRetryOptions interface defines how the websocket client should behave when a connection is lost. You can control the maximum number of attempts, whether to attempt an immediate reconnection, and the delay strategy used between retries.

    const retryOptions: WebsocketConnectionRetryOptions = {
      maxRetries: 5,
      instantReconnect: true,
      backoff: new Backoff(...) // Requires a Backoff instance
    };