npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

sturdy-websocket

v0.2.1

Published

Tiny WebSocket wrapper that reconnects and resends failed messages.

Downloads

273,548

Readme

Sturdy WebSocket

Tiny WebSocket wrapper that reconnects and resends failed messages.

Build
Status

Introduction

Sturdy WebSocket is a small (< 4kb gzipped) wrapper around a WebSocket that reconnects when the WebSocket closes. If send() is called while the backing WebSocket is closed, then the messages are stored in a buffer and sent once the connection is reestablished.

SturdyWebSocket fully implements the WebSocket API as described by MDN, including the ready state constants, the EventTarget interface, and properties that you probably don't care about like bufferedAmount. This means that it can be used as a drop-in replacement for WebSocket with any existing code or other libraries that consume WebSockets. To the surrounding code, SturdyWebSocket looks exactly like a regular WebSocket that never goes down, even in the presence of network failures.

Table of Contents

Usage

import SturdyWebSocket from "sturdy-websocket";

const ws = new SturdyWebSocket("wss://example.com");
ws.onopen = () => ws.send("Hello!");
ws.onmessage = event => console.log("I got a message that says " + event.data);
// Or if you prefer event listeners:
ws.addEventListener("message", event =>
    console.log("I already said this, but the message says " + event.data));

// Like with normal WebSockets, the protocol can be given as a second argument.
const wsWithProtocol = new SturdyWebSocket("wss://foo.com", "some-protocol");

// Options can be provided as the final argument.
const wsWithOptions = new SturdyWebSocket("wss://bar.com", {
    connectTimeout: 5000,
    maxReconnectAttempts: 5
    reconnectBackoffFactor: 1.3
});

Because it is imitating a regular WebSocket, onclose will only be called once, after the SturdyWebSocket is closed permanently either by using close() or because the shouldReconnect option returned false. If you are interested in being notified when the backing connection is temporarily down, you may listen for the additional events "down" and "reopen":

const ws = new SturdyWebSocket("wss://example.com");
ws.ondown = closeEvent => console.log("Closed for reason " + closeEvent.reason);
ws.onreopen = () => console.log("We're back up!");
// Or with event listeners
ws.addEventListener("down", closeEvent => "Yea, it's down.");

Caveats

While Sturdy WebSockets are more reliable than standard WebSockets, there is still an important failure case of which you should be aware. While rare, note that it is possible for the connection to die without the client being aware, such as if the power cord is pulled on the server. When this happens the Sturdy WebSocket will not know to open a new connection as this cannot be detected through the WebSocket protocol alone (at least without ping messages, which cannot be sent from the browser client).

To avoid this, it is recommended that you manually watch for disconnected sockets by periodically sending messages over the socket and checking for a response (a "ping/pong" system). If you detect that the connection has died, you should call the `reconnect() method to force a new connection to be created.

Further, note that any messages sent to the server while the connection is in this undetected dead state will be lost. To guarantee delivery of messages, you must have the server send back a response to acknowledge the message has been received.

Installation

With Yarn:

yarn add sturdy-websocket

With NPM:

npm install --save sturdy-websocket

Full API

As discussed above, SturdyWebSocket starts off by fully implementing the WebSocket API. Only features beyond the standard API are discussed below.

Options

Options are passed as an optional final argument to the constructor, for example:

import SturdyWebSocket from "sturdy-websocket";

const ws1 = new SturdyWebSocket("wss://foo.com", { maxReconnectAttempts: 5 });
const ws2 = new SturdyWebSocket("wss://bar.com", "some-protocol", {
    connectTimeout: 4000,
    reconnectBackoffFactor: 1.3,
});

All options which represent durations are in milliseconds.

allClearResetTime

Default: 5000

If a newly opened WebSocket closes immediately, it is considered to be a failed connection for the purposes of increasing time between attempts and counting towards maxReconnectAttempts. This option controls how long a connection must remain open to be considered "successful" and reset these values.

connectTimeout

Default: 5000

When attempting to open a new connection, how long to wait before giving up and making a new connection. Note that it is possible for an attempt to open a WebSocket to stall forever, which is why this option is needed.

debug

Default: false

If true, print various debug information to console.log, such as notifying about reconnect attempts.

minReconnectDelay

Default: 1000

The minimum positive time between failed reconnect attempts. Note that the first reconnect attempt happens immediately on the first failure, so this is actually the delay between the first and second reconnect attempts.

maxReconnectDelay

Default: 30000

The maximum time between failed reconnect attempts. Additional attempts will repeatedly use this as their delay.

maxReconnectAttempts

Default: Infinity

If reconnects fail this many times in a row, then the SturdyWebSocket closes permanently, providing the CloseEvent from the last failed reconnect attempt.

reconnectBackoffFactor

Default: 1.5

The factor by which the time between reconnect attempts increases after each failure.

shouldReconnect

Default: () => true

A function which returns either a boolean or a promise resolving to a boolean, which is called when the backing WebSocket closes to determine if a reconnect attempt should be made. It is provided the CloseEvent as an argument. For example:

const ws = new SturdyWebSocket("wss://example.com", {
    shouldReconnect: closeEvent => closeEvent.reason === "Harmless error",
});

If this returns false, then the SturdyWebSocket is closed and onclose is called with the latest CloseEvent. If this returns a promise, then the socket waits for that promise to resolve to a boolean before either attempting to reconnect or closing.

wsConstructor

Default: WebSocket

Constructor used for creating WebSockets internally. Can be used to specify an implementation for the underlying WebSockets other than the default. This may be useful in environments where WebSocket is not available as a global variable, such as Node.js.

If this option is not provided and there is no variable named WebSocket in the global scope, then the SturdyWebSocket constructor will throw.

Additional Methods

reconnect()

Closes the backing websocket and opens a new one. This will immediately call the down handler with no event, followed by the reopen handler once the connection is reestablished.

This is a useful method because the WebSocket protocol alone is not always enough to detect a failed connection. If you detect that this has occurred, for example by noticing that your messages sent do not receive a response, then you should manually call reconnect() to force a new connection to be created. See the Caveats section for details.

Additional Events

These events, like all the standard WebSocket events, can be observed in two ways:

ws.onreopen = () => console.log("We're back!");
ws.addEventListener("reopen", () => console.log("We're back!"));

down

Called when the backing WebSocket is closed but SturdyWebSocket will try to reconnect. Recieves the CloseEvent of the backing WebSocket. If this was triggered by a call to reconnect(), then the event will be undefined.

reopen

Called when the backing WebSocket is reopened after it closed.

Copyright © 2017 David Philipson