@gedeagas/react-universal-websocket
v1.1.6
Published
Universal Websocket Hooks for React & React Native
Downloads
32
Readme
react-universal-websocket
react-universal-websocket
This library is compatible with both React and React Native, offering powerful and flexible React hooks to simplify the management of WebSocket connections. It features seamless WebSocket integration within your applications, including capabilities like automatic reconnection, offline message queuing, and the ability to share WebSocket connections across components. Additionally, it provides typed support for both TypeScript and Flow, ensuring robust type safety for your projects.
🇨🇳 中文文档
Table of Contents
Installation
To install the useWebSocket
hook, you can use npm or yarn:
npm install @gedeagas/react-universal-websocket
Or using Yarn:
yarn add @gedeagas/react-universal-websocket
Usage
Here's a basic example of how to use the useWebSocket
hook in a React component:
import React, { useEffect } from 'react';
import { useWebSocket, ReadyState } from '@gedeagas/react-universal-websocket';
const WebSocketExample = () => {
const { sendMessage, lastMessage, readyState } = useWebSocket('ws://example.com/socket');
useEffect(() => {
if (lastMessage !== null) {
console.log('Received message:', lastMessage.data);
}
}, [lastMessage]);
const handleClick = () => {
sendMessage('Hello, server!');
};
const connectionStatus = {
[ReadyState.CONNECTING]: 'Connecting',
[ReadyState.OPEN]: 'Open',
[ReadyState.CLOSING]: 'Closing',
[ReadyState.CLOSED]: 'Closed',
[ReadyState.UNINSTANTIATED]: 'Uninstantiated',
}[readyState];
return (
<div>
<button onClick={handleClick}>Send Message</button>
<p>Connection Status: {connectionStatus}</p>
{lastMessage && <p>Last message: {lastMessage.data}</p>}
</div>
);
};
export default WebSocketExample;
Options
The useWebSocket
hook accepts a configuration object with various options to customize the behavior of the WebSocket connection:
queryParams
(QueryParams): An object containing query parameters to append to the WebSocket URL.protocols
(string | string[]): A string or array of strings representing the subprotocols.share
(boolean): Iftrue
, allows sharing of the WebSocket instance among multiple hooks.onOpen
(function): A callback function for when the WebSocket connection opens.onClose
(function): A callback function for when the WebSocket connection closes.onMessage
(function): A callback function for handling incoming messages.onError
(function): A callback function for handling errors.onReconnectStop
(function): A callback function called when reconnection attempts stop.shouldReconnect
(function): A function that determines whether to attempt reconnection.reconnectInterval
(number | function): The interval between reconnection attempts.reconnectAttempts
(number): The maximum number of reconnection attempts allowed.filter
(function): A function to filter incoming messages.retryOnError
(boolean): Iftrue
, retries connection on error.skipAssert
(boolean): Iftrue
, skips WebSocket assertion checks.heartbeat
(boolean | HeartbeatOptions): Enables heartbeat messages to keep the connection alive.
Here's a comprehensive documentation for the useWebSocket
hook options, along with examples for each. This should help developers understand and utilize the different configuration options available.
queryParams
An object containing query parameters to append to the WebSocket URL.
- Type:
{ [key: string]: string | number }
Example:
const options = {
queryParams: { token: 'abcd1234' },
};
const { sendMessage, lastMessage, readyState } = useWebSocket('ws://example.com/socket', options);
protocols
A string or array of strings representing the subprotocols.
- Type:
string | string[]
Example:
const options = {
protocols: ['protocolOne', 'protocolTwo'],
};
const { sendMessage, lastMessage, readyState } = useWebSocket('ws://example.com/socket', options);
share
If true
, allows sharing of the WebSocket instance among multiple hooks.
- Type:
boolean
- Default:
false
Example:
const options = {
share: true,
};
const { sendMessage, lastMessage, readyState } = useWebSocket('ws://example.com/socket', options);
onOpen
A callback function for when the WebSocket connection opens.
- Type:
(event: WebSocketEventMap["open"]) => void
Example:
const options = {
onOpen: (event) => console.log('Connection opened!', event),
};
const { sendMessage, lastMessage, readyState } = useWebSocket('ws://example.com/socket', options);
onClose
A callback function for when the WebSocket connection closes.
- Type:
(event: WebSocketEventMap["close"]) => void
Example:
const options = {
onClose: (event) => console.log('Connection closed!', event),
};
const { sendMessage, lastMessage, readyState } = useWebSocket('ws://example.com/socket', options);
onMessage
A callback function for handling incoming messages.
- Type:
(event: WebSocketEventMap["message"]) => void
Example:
const options = {
onMessage: (event) => console.log('Message received!', event.data),
};
const { sendMessage, lastMessage, readyState } = useWebSocket('ws://example.com/socket', options);
onError
A callback function for handling errors.
- Type:
(event: WebSocketEventMap["error"]) => void
Example:
const options = {
onError: (event) => console.log('Error occurred!', event),
};
const { sendMessage, lastMessage, readyState } = useWebSocket('ws://example.com/socket', options);
onReconnectStop
A callback function called when reconnection attempts stop.
- Type:
(numAttempts: number) => void
Example:
const options = {
onReconnectStop: (numAttempts) => console.log(`Reconnection stopped after ${numAttempts} attempts`),
};
const { sendMessage, lastMessage, readyState } = useWebSocket('ws://example.com/socket', options);
shouldReconnect
A function that determines whether to attempt reconnection.
- Type:
(event: WebSocketEventMap["close"]) => boolean
Example:
const options = {
shouldReconnect: (event) => true, // Always attempt to reconnect
};
const { sendMessage, lastMessage, readyState } = useWebSocket('ws://example.com/socket', options);
reconnectInterval
The interval between reconnection attempts.
- Type:
number | (lastAttemptNumber: number) => number
Example:
const options = {
reconnectInterval: 5000, // 5 seconds
};
const { sendMessage, lastMessage, readyState } = useWebSocket('ws://example.com/socket', options);
reconnectAttempts
The maximum number of reconnection attempts allowed.
- Type:
number
Example:
const options = {
reconnectAttempts: 3, // Max 3 reconnection attempts
};
const { sendMessage, lastMessage, readyState } = useWebSocket('ws://example.com/socket', options);
filter
A function to filter incoming messages.
- Type:
(message: WebSocketEventMap["message"]) => boolean
Example:
const options = {
filter: (message) => message.data !== 'ignore', // Ignore messages with data 'ignore'
};
const { sendMessage, lastMessage, readyState } = useWebSocket('ws://example.com/socket', options);
retryOnError
If true
, retries connection on error.
- Type:
boolean
- Default:
false
Example:
const options = {
retryOnError: true,
};
const { sendMessage, lastMessage, readyState } = useWebSocket('ws://example.com/socket', options);
skipAssert
If true
, skips WebSocket assertion checks.
- Type:
boolean
- Default:
false
Example:
const options = {
skipAssert: true,
};
const { sendMessage, lastMessage, readyState } = useWebSocket('ws://example.com/socket', options);
heartbeat
Enables heartbeat messages to keep the connection alive.
- Type:
boolean | HeartbeatOptions
Example:
const options = {
heartbeat: {
message: 'ping',
returnMessage: 'pong',
timeout: 3000, // 3 seconds
interval: 10000, // 10 seconds
},
};
const { sendMessage, lastMessage, readyState } = useWebSocket('ws://example.com/socket', options);
Complete Usage Example
Here’s a complete example using several options together:
import useWebSocket from 'react-use-websocket';
function App() {
const options = {
queryParams: { token: 'abcd1234' },
protocols: ['protocolOne', 'protocolTwo'],
share: true,
onOpen: (event) => console.log('Connection opened!', event),
onClose: (event) => console.log('Connection closed!', event),
onMessage: (event) => console.log('Message received!', event.data),
onError: (event) => console.log('Error occurred!', event),
onReconnectStop: (numAttempts) => console.log(`Reconnection stopped after ${numAttempts} attempts`),
shouldReconnect: (event) => true, // Always attempt to reconnect
reconnectInterval: (attemptNumber) => Math.min(Math.pow(2, attemptNumber) * 1000, 10000), // Exponential backoff
reconnectAttempts: 10, // Max 10 reconnection attempts
filter: (message) => message.data !== 'ignore', // Ignore messages with data 'ignore'
retryOnError: true,
skipAssert: true,
heartbeat: {
message: 'ping',
returnMessage: 'pong',
timeout: 3000, // 3 seconds
interval: 10000, // 10 seconds
},
};
const { sendMessage, lastMessage, readyState } = useWebSocket('ws://example.com/socket', options);
return (
<div>
<p>Ready State: {readyState}</p>
<p>Last Message: {lastMessage ? lastMessage.data : 'No message yet'}</p>
<button onClick={() => sendMessage('Hello WebSocket!')}>Send Message</button>
</div>
);
}
export default App;
This documentation and the accompanying examples should help you understand and leverage the various options provided by the useWebSocket
hook.
API
The useWebSocket
hook provides the following API:
sendMessage
: A function to send a message to the WebSocket server.sendJsonMessage
: A function to send a JSON message to the WebSocket server.lastMessage
: The last message received from the WebSocket server.lastJsonMessage
: The last parsed JSON message received from the WebSocket server.readyState
: The current state of the WebSocket connection.getWebSocket
: A function to get the current WebSocket instance.
Types
- QueryParams: An object mapping strings or numbers to query parameter keys.
- WebSocketMessage: Types of messages that can be sent:
string
,ArrayBuffer
,SharedArrayBuffer
,Blob
, orArrayBufferView
. - SendMessage: A function type to send WebSocket messages.
- SendJsonMessage: A function type to send JSON messages.
- WebSocketHook: The hook return type, including methods and state properties related to the WebSocket connection.
Advanced Usage
Sharing WebSocket Connections
To share a WebSocket connection among multiple components, set the share
option to true
. This ensures that a single WebSocket instance is reused, reducing the overhead of multiple connections.
const options = {
share: true,
};
const { sendMessage, lastMessage, readyState } = useWebSocket('ws://example.com/socket', options);
Handling Heartbeats
Heartbeats can keep the connection alive by sending periodic messages. Use the heartbeat
option to enable and configure heartbeats:
const options = {
heartbeat: {
message: 'ping', // Message sent as heartbeat
returnMessage: 'pong', // Expected return message
timeout: 10000, // Time to wait for return message
interval: 30000, // Interval between heartbeats
},
};
const { sendMessage, lastMessage, readyState } = useWebSocket('ws://example.com/socket', options);
Custom Reconnection Logic
When dealing with WebSocket connections, it's important to handle reconnections gracefully to ensure reliability. This can be achieved using the shouldReconnect
, reconnectInterval
, and reconnectAttempts
options.
Here's an example of how you can configure these options:
Exponential Backoff
Alternatively, you can provide a function for reconnectInterval
that accepts the nth last attempt as a parameter and returns a number. This can be useful for employing more advanced reconnect strategies like Exponential Backoff:
const exponentialBackoffOptions = {
shouldReconnect: (closeEvent) => true,
reconnectAttempts: 10, // Max 10 reconnection attempts
// attemptNumber starts at 0, resulting in a pattern of 1 second, 2 seconds, 4 seconds, 8 seconds, and then caps at 10 seconds
reconnectInterval: (attemptNumber) =>
Math.min(Math.pow(2, attemptNumber) * 1000, 10000),
};
const { sendMessage, lastMessage, readyState } = useWebSocket(
'wss://echo.websocket.org',
exponentialBackoffOptions
);
Fibonacci Backoff
Another algorithm for reconnection is the Fibonacci Backoff, which uses the Fibonacci sequence to determine the wait time between reconnections. Here's how you can implement it:
const fibonacciBackoffOptions = {
shouldReconnect: (closeEvent) => true,
reconnectAttempts: 10, // Max 10 reconnection attempts
reconnectInterval: (attemptNumber) => {
const fibonacci = (n) => {
if (n <= 1) return 1;
return fibonacci(n - 1) + fibonacci(n - 2);
};
// Cap at 60 seconds
return Math.min(fibonacci(attemptNumber + 1) * 1000, 60000);
},
};
const { sendMessage, lastMessage, readyState } = useWebSocket(
'wss://echo.websocket.org',
fibonacciBackoffOptions
);
By customizing the reconnectInterval
function, you can control the reconnection strategy and improve the reliability and performance of your WebSocket connections based on your application's needs.
Acknowledgements
This project is a fork of react-use-websocket and is also inspired by react-native-reconnecting-websocket. We extend our gratitude to the authors and contributors of these projects for their excellent work and inspiration.
Contributing
Contributions are welcome! Please feel free to submit a pull request or open an issue.
- Fork the repository.
- Create a new branch (
git checkout -b feature-branch
). - Commit your changes (
git commit -m 'Add new feature'
). - Push to the branch (
git push origin feature-branch
). - Open a pull request.
License
This project is licensed under the MIT License. See the LICENSE file for more information.