Auto reconnect WebSocket client for browsers.
reconnect-websocket wraps the native WebSocket API and adds automatic
reconnect, message queueing while connecting, Promise-based sending, reply
waiting, and a small event emitter.
- Automatic connection on initialization.
- Automatic reconnect after unexpected close.
- Manual
connect,reconnect, andclosecontrols. - Message queue while the socket is still connecting.
- Promise-based
send. - Optional reply waiting with timeout.
beforeSendHookfor outgoing message normalization.beforeEmitHookfor incoming message parsing and event routing.- Native WebSocket state constants and common read-only properties.
- TypeScript source and declaration file.
This package is designed for browsers that support:
WebSocketPromiseObject.defineProperty
For older browsers, provide the required polyfills before creating a socket.
This repository contains the source package. Build it before using the files in
dist/.
npm install
npm run buildAfter build, the generated files are:
dist/reconnect-websocket.js- UMD build for browsers.dist/reconnect-websocket.common.js- CommonJS build.dist/reconnect-websocket.esm.js- ES module build.
Note: verify the npm package name before publishing or installing from npm. The package name in this repository is
reconnect-websocket.
import ReconnectWebsocket from 'reconnect-websocket'
const socket = new ReconnectWebsocket('ws://localhost:3000')
socket.on('open', () => {
socket.send('hello')
})
socket.on('message', event => {
console.log(event.data)
})
socket.on('close', event => {
console.log('socket closed', event)
})
socket.on('error', error => {
console.error(error)
})By default, incoming messages emit the native message event. If your server
sends JSON payloads with a type field, use beforeEmitHook to route messages
to custom events.
const socket = new ReconnectWebsocket('ws://localhost:3000', {
beforeEmitHook(event) {
return JSON.parse(event.data)
}
})
socket.on('chat', event => {
console.log(event.data)
})For example, the server message below will trigger the chat listener:
{
"type": "chat",
"data": "hello"
}Return false from beforeEmitHook to ignore a message.
send(data, options) returns a Promise. If options.rep is provided, the
Promise resolves when an event with that name is emitted. If the event is not
received before options.timeout, the Promise rejects.
const socket = new ReconnectWebsocket('ws://localhost:3000', {
beforeEmitHook(event) {
return JSON.parse(event.data)
}
})
socket
.send(
{ type: 'ping', data: Date.now() },
{
rep: 'pong',
timeout: 3000
}
)
.then(pongEvent => {
console.log('reply received', pongEvent.data)
})
.catch(error => {
console.error('wait reply failed', error)
socket.reconnect()
})Creates a reconnecting WebSocket instance.
const socket = new ReconnectWebsocket('ws://localhost:3000', {
reconnect: true,
autoconnect: true,
reconnectTime: 10
})Sends data to the server and returns a Promise.
socket.send('hello')
socket.send({ type: 'chat', data: 'hello' }, {
rep: 'chat-ack',
timeout: 5000,
retry: true
})Objects are serialized with JSON.stringify before sending.
Connects to a WebSocket URL. If url is omitted, the last connected URL is
used.
socket.connect('ws://localhost:3000')Closes the current socket and connects again with the last URL.
socket.reconnect()Closes the socket and disables automatic reconnect for this close operation.
socket.close(1000, 'normal close')Registers an event listener. Returns an off function.
const off = socket.on('message', event => {
console.log(event.data)
})
off()Registers a listener that runs once.
socket.once('connect', () => {
console.log('first connection opened')
})Removes an event listener.
function handleMessage(event) {
console.log(event.data)
}
socket.on('message', handleMessage)
socket.off('message', handleMessage)| Name | Type | Default | Description |
|---|---|---|---|
protocol |
string | string[] |
'' |
WebSocket subprotocol passed to the native constructor. |
reconnect |
boolean |
true |
Whether to reconnect automatically after unexpected close. |
autoconnect |
boolean |
true |
Whether to connect immediately in the constructor. |
reconnectTime |
number |
10 |
Maximum automatic reconnect counter before emitting reconnet-fail. |
binaryType |
'blob' | 'arraybuffer' |
'blob' |
Binary data type for the native WebSocket. |
beforeSendHook |
function |
undefined |
Hook called before each send. |
beforeEmitHook |
function |
undefined |
Hook called before each incoming message is emitted. |
Use this hook to normalize outgoing messages.
const socket = new ReconnectWebsocket('ws://localhost:3000', {
beforeSendHook(options, send) {
options.data = JSON.stringify({
type: options.type || 'message',
data: options.data
})
send(options)
}
})Use this hook to parse incoming messages. It must return an object with a
type property, or false to ignore the message.
const socket = new ReconnectWebsocket('ws://localhost:3000', {
beforeEmitHook(event) {
try {
return JSON.parse(event.data)
} catch (error) {
return false
}
}
})| Name | Type | Default | Description |
|---|---|---|---|
rep |
string |
undefined |
Event name to wait for after sending. |
timeout |
number |
10000 |
Reply wait timeout in milliseconds. |
retry |
boolean |
true |
Queue the message if the socket is still connecting. |
| Event | Description |
|---|---|
open |
Native WebSocket open event. |
connect |
First successful connection. |
reconnect |
Successful connection after reconnect. |
message |
Native WebSocket message event when no custom beforeEmitHook changes the event type. |
close |
Native WebSocket close event. |
error |
Native WebSocket error or internal send error. |
reconnet-fail |
Emitted when automatic reconnect exceeds the retry counter. The event name keeps the current source spelling. |
| Custom event | Any event object returned by beforeEmitHook with a type field. |
| Property | Description |
|---|---|
readyState |
Current native WebSocket state. |
binaryType |
Gets or sets the native binaryType. |
bufferedAmount |
Native buffered amount. |
extensions |
Native selected extensions. |
protocol |
Native selected protocol. |
Static state constants are also available:
ReconnectWebsocket.CONNECTING
ReconnectWebsocket.OPEN
ReconnectWebsocket.CLOSING
ReconnectWebsocket.CLOSEDconst socket = new ReconnectWebsocket('ws://localhost:3000', {
beforeEmitHook(event) {
return JSON.parse(event.data)
}
})
socket.on('open', () => {
setInterval(() => {
const time = Date.now()
socket
.send(
{ type: 'ping', data: time },
{ rep: 'pong', timeout: 3000 }
)
.then(event => {
console.log('heartbeat ok', event.data)
})
.catch(() => {
socket.reconnect()
})
}, 5000)
})See example/heartbeat for a runnable browser example.
npm install
npm run build
npm testThe project is written in TypeScript and exposes declaration files through the
types field.
import ReconnectWebsocket from 'reconnect-websocket'
const socket = new ReconnectWebsocket('ws://localhost:3000')MIT