Skip to content

useWebSocket

Category
Export Size
1.28 kB
Last Changed
5 days ago

Reactive WebSocket client

Demo

Usage

tsx
import { 
useWebSocket
} from '@reause/core'
const {
status
,
data
,
send
,
open
,
close
,
ws
} =
useWebSocket
('ws://websocketurl')

Return Values

PropertyTypeDescription
dataT | nullLatest received data
status'OPEN' | 'CONNECTING' | 'CLOSED'Connection status
wsWebSocket | undefinedWebSocket instance
send(data, useBuffer?) => booleanSend data (buffers if not connected)
open() => voidOpen/reconnect the connection
close(code?, reason?) => voidClose the connection

Callbacks

tsx
const { 
data
} =
useWebSocket
('ws://websocketurl', {
onConnected
(
ws
) {
console
.
log
('Connected!')
},
onDisconnected
(
ws
,
event
) {
console
.
log
('Disconnected!',
event
.
code
)
},
onError
(
ws
,
event
) {
console
.
error
('Error:',
event
)
},
onMessage
(
ws
,
event
) {
console
.
log
('Message:',
event
.
data
)
}, })

immediate

Enable by default.

Establish the connection immediately when the hook is called.

autoConnect

Enable by default.

If the URL changes between renders (plain value or React ref), it will automatically reconnect to the new URL.

autoClose

Enable by default.

This will call close() automatically when the beforeunload event is triggered or the component unmounts.

autoReconnect

Reconnect on errors automatically (disabled by default).

tsx
import { 
useWebSocket
} from '@reause/core'
const {
status
,
data
,
close
} =
useWebSocket
('ws://websocketurl', {
autoReconnect
: true,
})

Or with more controls over its behavior:

tsx
import { 
useWebSocket
} from '@reause/core'
const {
status
,
data
,
close
} =
useWebSocket
('ws://websocketurl', {
autoReconnect
: {
retries
: 3,
delay
: 1000,
onFailed
() {
alert
('Failed to connect WebSocket after 3 retries')
}, }, })

You can also pass a function to delay to calculate the delay based on the number of retries. This is useful for implementing exponential backoff:

tsx
import { 
useWebSocket
} from '@reause/core'
const {
status
,
data
,
close
} =
useWebSocket
('ws://websocketurl', {
autoReconnect
: {
retries
: 5,
// Exponential backoff: 1s, 2s, 4s, 8s, 16s
delay
:
retries
=>
Math
.
min
(1000 * 2 ** (
retries
- 1), 30000),
}, })

Explicitly calling close() won't trigger the auto reconnection.

heartbeat

It's common practice to send a small message (heartbeat) for every given time passed to keep the connection active. In this function we provide a convenient helper to do it:

tsx
import { 
useWebSocket
} from '@reause/core'
const {
status
,
data
,
close
} =
useWebSocket
('ws://websocketurl', {
heartbeat
: true,
})

Or with more controls:

tsx
import { 
useWebSocket
} from '@reause/core'
const {
status
,
data
,
close
} =
useWebSocket
('ws://websocketurl', {
heartbeat
: {
message
: 'ping',
scheduler
: (
cb
) => {
// any timer wiring returning `{ pause, resume }` works let
id
=
setInterval
(
cb
, 2000)
return {
pause
: () =>
clearInterval
(
id
),
resume
: () => {
id
=
setInterval
(
cb
, 2000) },
} },
pongTimeout
: 1000,
}, })

Sub-protocols

List of one or more subprotocols to use, in this case SOAP and WAMP.

tsx
import { 
useWebSocket
} from '@reause/core'
const {
status
,
data
,
send
,
open
,
close
} =
useWebSocket
('ws://websocketurl', {
protocols
: ['soap'], // ['soap', 'wamp']
})

Type Declarations

Toggle
ts
export type WebSocketStatus = 'OPEN' | 'CONNECTING' | 'CLOSED'

export type WebSocketHeartbeatMessage = string | ArrayBuffer | Blob | (() => string | ArrayBuffer | Blob)

export interface UseWebSocketOptions {
    onConnected?: (ws: WebSocket) => void;
    onDisconnected?: (ws: WebSocket, event: CloseEvent) => void;
    onError?: (ws: WebSocket, event: Event) => void;
    onMessage?: (ws: WebSocket, event: MessageEvent) => void;
    heartbeat?: boolean | {
        message?: WebSocketHeartbeatMessage;
        responseMessage?: WebSocketHeartbeatMessage;
        pongTimeout?: number;
        scheduler?: (fn: () => void) => {
            pause: () => void;
            resume: () => void;
        };
    };
    autoReconnect?: boolean | {
        retries?: number | ((retried: number) => boolean);
        delay?: number | ((retries: number) => number);
        onFailed?: () => void;
    };
    immediate?: boolean;
    autoConnect?: boolean;
    autoClose?: boolean;
    protocols?: string[];
}

export interface UseWebSocketReturn<T> {
    data: T | null;
    status: WebSocketStatus;
    close: WebSocket['close'];
    open: () => void;
    send: (data: string | ArrayBuffer | Blob, useBuffer?: boolean) => boolean;
    ws: WebSocket | undefined;
}

type WebSocketUrl = string | URL | undefined

export function useWebSocket<Data = any>(url: WebSocketUrl, options?: UseWebSocketOptions): UseWebSocketReturn<Data>

Source

Source · Demo · VueUse

Contributors

hairyf

Changelog

v0.1.0 on
def0e - fix(core): resolve useWebSocket audit findings (#692)
8fddc - chore!: remove all Vue-only Maybe* types and getter unions, adopt React Ref (#462)

Released under the MIT License. v0.1.8