JavaScript Development Space

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;
20
21 this.connect();
22 }
23
24 connect() {
25 this.ws = new WebSocket(this.url);
26
27 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 };
36
37 this.ws.onmessage = (event) => {
38 if (event.data === JSON.stringify({ type: "heartbeat" })) {
39 this.resetHeartbeatTimeout();
40 }
41 this.options.onMessage?.(event);
42 };
43
44 this.ws.onclose = (event) => {
45 console.log(`WebSocket closed: ${event.code} ${event.reason}`);
46 this.stopHeartbeat();
47 this.options.onClose?.(event);
48
49 if (!this.isReconnecting && event.code !== 1000) {
50 this.reconnect();
51 }
52 };
53
54 this.ws.onerror = (error) => {
55 console.error("WebSocket error:", error);
56 this.options.onError?.(error);
57 };
58 }
59
60 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 }
68
69 stopHeartbeat() {
70 clearInterval(this.heartbeatTimer);
71 clearTimeout(this.heartbeatTimeoutId);
72 }
73
74 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 }
84
85 resetHeartbeatTimeout() {
86 this.heartbeatTimeouts = 0;
87 this.setHeartbeatTimeout();
88 }
89
90 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.maxReconnectInterval
96 );
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 }
106
107 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 }
114
115 flushMessageQueue() {
116 while (this.messageQueue.length > 0) {
117 this.send(this.messageQueue.shift());
118 }
119 }
120
121 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 });
9
10 // Send a message
11 wsClient.send({ type: "message", content: "Hello, Server!" });
12
13 // Close the connection manually
14 // 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.

JavaScript Development Space

© 2025 JavaScript Development Space - Master JS and NodeJS. All rights reserved.