How to Implement Reliable WebSocket Reconnection Logic with Ease
WebSockets are a powerful tool for real-time communication between a client and a server. However, handling connection interruptions and ensuring reliability can be challenging. This guide demonstrates how to implement a robust WebSocket encapsulation with automatic reconnection, event listeners, and customizable parameters.
Why Encapsulate WebSocket Logic?
By encapsulating WebSocket logic, you:
- Simplify implementation across your app.
- Handle reconnection automatically without duplicating code.
- Improve maintainability and scalability.
Key Features of the WebSocket Encapsulation
- Automatic Reconnection: Retry connecting after disconnections with configurable parameters.
- Event Listeners: Add and manage WebSocket events like
open
,close
, anderror
. - Customizable Parameters: Control maximum reconnection attempts, intervals, and timeout limits.
- Error Handling: Gracefully handle errors and provide feedback.
Implementation: WebSocketReconnect Class
Below is the complete implementation of a WebSocketReconnect class:
js
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
class WebSocketReconnect {
constructor(
url,
maxReconnectAttempts = 3,
reconnectInterval = 20000,
maxReconnectTime = 180000
) {
this.url = url;
this.maxReconnectAttempts = maxReconnectAttempts;
this.reconnectInterval = reconnectInterval;
this.maxReconnectTime = maxReconnectTime;
this.reconnectCount = 0;
this.reconnectTimeout = null;
this.startTime = null;
this.socket = null;
this.listenerEvents = {};
if (this.checkWssUrl()) {
this.connect();
}
}
checkWssUrl(url = this.url) {
if (/wss:\/\/.*/.test(url) || /ws:\/\/.*/.test(url)) {
return true;
} else {
console.error('Invalid WebSocket URL');
return false;
}
}
connect() {
console.log('Connecting...');
this.socket = new WebSocket(this.url);
this.socket.onopen = () => {
console.log('WebSocket Connection Opened');
this.triggerEvent('open');
this.clearReconnectTimeout();
this.reconnectCount = 0;
};
this.socket.onclose = event => {
console.log('WebSocket Connection Closed', event);
this.triggerEvent('close');
this.handleReconnect();
};
this.socket.onerror = error => {
console.error('WebSocket Error', error);
this.triggerEvent('error');
this.handleReconnect();
};
}
triggerEvent(type) {
const events = this.listenerEvents[type] || [];
events.forEach(callback => callback());
}
addEventListener(type, callback) {
if (!this.listenerEvents[type]) {
this.listenerEvents[type] = [];
}
this.listenerEvents[type].push(callback);
}
handleReconnect() {
if (
this.reconnectCount < this.maxReconnectAttempts &&
(!this.startTime || Date.now() - this.startTime < this.maxReconnectTime)
) {
this.reconnectCount++;
console.log(
`Reconnecting (${this.reconnectCount}/${this.maxReconnectAttempts})...`
);
this.reconnectTimeout = setTimeout(() => {
this.connect();
}, this.reconnectInterval);
if (!this.startTime) {
this.startTime = Date.now();
}
} else {
console.log('Max reconnection attempts reached or timeout exceeded.');
}
}
clearReconnectTimeout() {
if (this.reconnectTimeout) {
clearTimeout(this.reconnectTimeout);
this.reconnectTimeout = null;
}
}
close() {
if (this.socket && this.socket.readyState === WebSocket.OPEN) {
this.socket.close();
}
this.clearReconnectTimeout();
this.reconnectCount = 0;
this.startTime = null;
}
}
Example Usage
Here’s how you can use the WebSocketReconnect class:
js
1234567891011121314151617181920
import WebSocketReconnect from './WebSocketReconnect';
import WebSocketReconnect from './WebSocketReconnect';
const ws = new WebSocketReconnect('ws://your-websocket-url');
ws.addEventListener('open', () => {
console.log('WebSocket opened');
});
ws.addEventListener('close', () => {
console.log('WebSocket closed');
});
ws.addEventListener('error', () => {
console.log('WebSocket encountered an error');
});
// Close the WebSocket connection when no longer needed
ws.close();
Key Methods Explained
- connect: Establishes the WebSocket connection and sets event listeners.
- handleReconnect: Implements reconnection logic with retry limits.
- addEventListener: Registers event listeners for WebSocket events.
- close: Closes the WebSocket connection and clears reconnection timers.
Benefits of Using This Encapsulation
- Reduced Boilerplate: Write less repetitive code for WebSocket management.
- Improved Reliability: Automatically recover from connection disruptions.
- Flexibility: Customize parameters like retry limits and intervals.
By following this guide, you can implement a reliable WebSocket encapsulation that simplifies handling real-time connections in your applications.