WebSocket Client JavaScript Implementation
Below is an improved and concise implementation of a WebSocketClient class. It handles connection management, reconnection logic, heartbeat mechanisms, and message queuing, making it robust for real-world applications.
WebSocket Client Class Implementation
js
1 class WebSocketClient {2 constructor(url, options = {}) {3 this.url = url;4 this.ws = null;5 this.options = {6 reconnectInterval: options.reconnectInterval || 5000,7 maxReconnectInterval: options.maxReconnectInterval || 60000,8 heartbeatInterval: options.heartbeatInterval || 30000,9 heartbeatTimeout: options.heartbeatTimeout || 10000,10 maxReconnectAttempts: options.maxReconnectAttempts || 5,11 maxHeartbeatTimeouts: options.maxHeartbeatTimeouts || 3,12 ...options,13 };14 this.reconnectAttempts = 0;15 this.heartbeatTimeouts = 0;16 this.messageQueue = [];17 this.heartbeatTimer = null;18 this.reconnectTimer = null;19 this.isReconnecting = false;2021 this.connect();22 }2324 connect() {25 this.ws = new WebSocket(this.url);2627 this.ws.onopen = () => {28 console.log("WebSocket connected");29 this.isReconnecting = false;30 this.reconnectAttempts = 0;31 this.heartbeatTimeouts = 0;32 this.startHeartbeat();33 this.flushMessageQueue();34 this.options.onOpen?.();35 };3637 this.ws.onmessage = (event) => {38 if (event.data === JSON.stringify({ type: "heartbeat" })) {39 this.resetHeartbeatTimeout();40 }41 this.options.onMessage?.(event);42 };4344 this.ws.onclose = (event) => {45 console.log(`WebSocket closed: ${event.code} ${event.reason}`);46 this.stopHeartbeat();47 this.options.onClose?.(event);4849 if (!this.isReconnecting && event.code !== 1000) {50 this.reconnect();51 }52 };5354 this.ws.onerror = (error) => {55 console.error("WebSocket error:", error);56 this.options.onError?.(error);57 };58 }5960 startHeartbeat() {61 this.heartbeatTimer = setInterval(() => {62 if (this.ws.readyState === WebSocket.OPEN) {63 this.ws.send(JSON.stringify({ type: "heartbeat" }));64 this.setHeartbeatTimeout();65 }66 }, this.options.heartbeatInterval);67 }6869 stopHeartbeat() {70 clearInterval(this.heartbeatTimer);71 clearTimeout(this.heartbeatTimeoutId);72 }7374 setHeartbeatTimeout() {75 clearTimeout(this.heartbeatTimeoutId);76 this.heartbeatTimeoutId = setTimeout(() => {77 console.warn("Heartbeat timeout");78 this.heartbeatTimeouts++;79 if (this.heartbeatTimeouts >= this.options.maxHeartbeatTimeouts) {80 this.ws.close();81 }82 }, this.options.heartbeatTimeout);83 }8485 resetHeartbeatTimeout() {86 this.heartbeatTimeouts = 0;87 this.setHeartbeatTimeout();88 }8990 reconnect() {91 this.isReconnecting = true;92 if (this.reconnectAttempts < this.options.maxReconnectAttempts) {93 const interval = Math.min(94 this.options.reconnectInterval * Math.pow(2, this.reconnectAttempts),95 this.options.maxReconnectInterval96 );97 this.reconnectTimer = setTimeout(() => {98 console.log(`Reconnecting... Attempt ${this.reconnectAttempts + 1}`);99 this.reconnectAttempts++;100 this.connect();101 }, interval);102 } else {103 console.error("Max reconnect attempts reached");104 }105 }106107 send(data) {108 if (this.ws.readyState === WebSocket.OPEN) {109 this.ws.send(JSON.stringify(data));110 } else {111 this.messageQueue.push(data);112 }113 }114115 flushMessageQueue() {116 while (this.messageQueue.length > 0) {117 this.send(this.messageQueue.shift());118 }119 }120121 close() {122 this.ws.close(1000, "Closed by client");123 this.stopHeartbeat();124 clearTimeout(this.reconnectTimer);125 }126 }
Key Features
1. Connection Management:
- Handles onopen, onclose, and onerror events gracefully.
- Reconnects automatically using exponential backoff.
2. Heartbeat Mechanism:
- Sends periodic heartbeat messages to keep the connection alive.
- Detects and handles heartbeat timeouts.
3. Reconnection Logic:
- Reconnects when the connection drops unexpectedly, with configurable limits.
- Stops reconnection attempts after reaching a maximum number of attempts.
4. Message Queue:
- Caches messages if the connection is closed and sends them once reconnected.
5. Customizable:
- Options like onOpen, onMessage, and onError allow for flexible callbacks.
Usage Example
js
1 const wsClient = new WebSocketClient("ws://example.com/socket", {2 reconnectInterval: 3000,3 maxReconnectAttempts: 3,4 onOpen: () => console.log("Connection established"),5 onMessage: (event) => console.log("Received:", event.data),6 onClose: (event) => console.log(`Disconnected: ${event.code}`),7 onError: (error) => console.error("Error:", error),8 });910 // Send a message11 wsClient.send({ type: "message", content: "Hello, Server!" });1213 // Close the connection manually14 // wsClient.close();
Summary
This WebSocketClient
class provides a robust solution for handling WebSocket connections, ensuring stability through reconnection, heartbeat, and message queuing. It is well-suited for real-time applications requiring persistent communication.