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

@jotter/websocket

v1.2.5

Published

Modern and useful WebSocket wrapper, with standard WebSocket API. Supports reconnection, keep alive and exception message handling.

Downloads

15

Readme

WebSocket

[ English | 中文 ]

version downloads size languages license

Modern and useful WebSocket wrapper, with standard WebSocket API. Supports keep alive, exception message handling and reconnection.

Feature

  • 🕰 Has the same API and call method as WebSocket;
  • ⚙️ Fully configurable;
  • 🧬 Automatic reconnection in case of abnormal disconnection, with customizable reconnection rules;
  • 📮 Message buffer (accumulated messages are sent when the connection is successful);
  • 💗 Built-in heartbeat detection method, always in a keep-alive state.

Install

npm

npm install @jotter/websocket

browser

https://cdn.jsdelivr.net/npm/@jotter/websocket/dist/index.global.js

Usage

Fully compatible with the WebSocket browser API, for specific usage, please refer to: MDN WebSocket API

import WebSocketConnect from '@jotter/websocket'

const socket = new WebSocketConnect('ws://127.0.0.1/ws', {
  // Connect immediately after instantiation
  autoOpen: true,
  // Automatically reconnect after abnormal disconnection
  shouldReconnect(event) {
    return ![1000, 1001, 1005].includes(event.code)
  },
  // Maximum number of automatic reconnections, no longer reconnected after exceeding
  maxReconnectAttempts: 20,
  // Heartbeat detection is turned off by default
  ping: false
})

// socket.onclose
socket.onerror = function(err) {
  console.error(err.message)
}
socket.onopen = function(event) {
  // Manually start heartbeat detection
  socket.send({ data: 'ping', token: 'xxxxxx' })
}
socket.onmessage = function(event) {
  // ...
}
// or
socket.addEventListener('message', function(event) {
  //
})

socket.close()

API

const socket = new WebSocketConnect(
  url: string,
  protocols?: string | string[],
  options?: Options
)

url

WebSocket connection Url.

  • Type: string

protocols

WebSocket connection protocol.

  • Type: string | string[]

Options

WebSocket connection options.

autoOpen

Whether to attempt to connect immediately upon instantiation.
You can manually open or close by calling ws.open() and ws.close().

  • Type: boolean
  • Default: true

shouldReconnect

Whether to automatically reconnect. By default, it will not reconnect for codes [1000, 1001, 1005].
You can set the reconnection rules in shouldReconnect(event, ctx).

  • Type: boolean | ((event: Event, context: any) => boolean)
  • Default: true

maxReconnectAttempts

Maximum number of reconnections

  • Type: number
  • Default: Infinity

reconnectInterval

The number of milliseconds to delay before attempting to reconnect. Unit: ms.

  • Type: number
  • Default: 1000

reconnectDecay

The rate at which the automatic reconnection delay increases, ranging from [0, 1].

  • Type: number
  • Default: 1

maxReconnectInterval

The maximum number of milliseconds to delay before attempting to reconnect. Unit: ms.

  • Type: number
  • Default: 30000

autoSend

Whether to automatically send queued messages after a successful connection.

  • Type: boolean
  • Default: false

maxMessageQueue

Maximum number of queued messages (No duplicate messages are saved).

  • Type: number
  • Default: Infinity

ping

Whether to enable heartbeat monitoring, if string then to send the message.
You can manually open or close by calling ws.ping().

  • Type: string | boolean
  • Default: false

pingInterval

Frequency of sending heartbeat detection. Unit: ms.

  • Type: number
  • Default: 5000

binaryType

The type of binary data transmitted by the WebSocket connection.

  • Type: 'blob' | 'arraybuffer'
  • Default: 'blob'

Events

open

WebSocket connection successful event.

  • onopen(event: Event): void

message

WebSocket message received event.

  • onmessage(event: MessageEvent): void

error

WebSocket connection error event.

  • onerror(event: ErrorEvent): void

close

WebSocket connection closed event.

  • onclose(event: CloseEvent): void

reconnect

WebSocket reconnection event.

  • onreconnect(event: Event): void

event.detail.count 可获取当前重连次数

reconnectend

WebSocket reconnection end event.

  • onreconnectend(event: Event): void

Instance Methods

open(reconnectAttempt?: boolean): void

Open the WebSocket connection.

  • reconnectAttempt - Whether it is a reconnection.

send(data: any): void;

Send a message.

  • data - Message content.

close(code?: number | string, reason?: string): void;

Close the WebSocket connection.

  • code - Close status code.
  • reason - Close reason.

ping(message?: boolean | string | object): void;

Heartbeat detection. 💓
Automatically enabled in the Options configuration or manually enabled or disabled by calling the ping() method.

  • message - Whether to enable heartbeat detection or heartbeat detection message body.
// Disable
socket.ping(false)
// Enable
socket.ping({ data: 'ping', token: 'xxxxxx' })

Examples

Use it with the event listener EventEmitter for a smoother experience.

Adjustment according to the actual situation:

import WebSocketConnect from '@jotter/websocket'
import EventEmitter from '@jotter/emitter'

const socket = new WebSocketConnect('ws://127.0.0.1', null, {})
const emitter = new EventEmitter()

socket.onmessage = function(event) {
  const data = JSON.parse(event.data)
  // Normal processing...
  emitter.emit(data.type, data.result)
}

/**
 * Socket request and listener
 * @param {string | any} type Listening message type or sending data
 * @param {any} data Sending data
 * @param {function} listener Message processing function
 * @param {object} options Configuration item, supports listening event processing once `{ once: true }`
 * @returns 
 */
// function request(data)
function request(type, data, listener, options = {}) {
  if (typeof listener === 'function') {
    addListener(type, listener, options)
  }
  // arguments.length=1, then request only supports send
  socket.send(arguments.length === 1 ? type : data)
  return { type, listener }
}

function addListener(type, listener, options = {}) {
  emitter[options.once ? 'once' : 'on'](type, listener)
  return { type, listener }
}
function removeListener(type, listener) {
  emitter.off(type, listener)
}

export {
  socket,
  emitter,
  request,
  addListener,
  removeListener
}

Specific usage:

// Send device real-time location message and listen for return data
const deviceCoord = request('device_coord', { deviceId: 9527 }, function(result) {
  // data = { type: 'device_coord', result: { id: 9527, lng: '32.48547', lat: '12.34849' } }
  const coord = [result.lng, result.lat]
})

// Only send messages
request({ device: 9527 })

// Remove device location listener
removeListener('device_coord', deviceCoord.listener)

refs