const WebSocket = require('ws'); class WebSocketClient { constructor(url, options = {},wsListener) { this.url = url; this.options = options; this.wsListener = wsListener this.reconnectDelay = options.reconnectDelay || 5000; this.heartbeatInterval = options.heartbeatInterval || 30000; this.heartbeatTimeout = options.heartbeatTimeout || 5000; this.ws = null; this.heartbeatTimer = null; this.reconnectTimer = null; this.heartbeatTimeoutTimer = null; this.connect(); } connect() { try { this.ws = new WebSocket(this.url); this.ws.on('open', () => { console.log('WebSocket connected'); this.startHeartbeat(); this.wsListener.onOpen(this.ws) }); this.ws.on('message', (data) => { this.handleMessage(data); }); this.ws.on('close', () => { console.log('WebSocket closed'); this.cleanup(); this.scheduleReconnect(); this.wsListener.onClosing() }); this.ws.on('error', (error) => { console.error('WebSocket error:', error); this.cleanup(); this.scheduleReconnect(); this.wsListener.onFailure() }); } catch (error) { console.error('Connection error:', error); this.scheduleReconnect(); this.wsListener.onFailure() } } handleMessage(data) { // Handle incoming messages const message = data.toString(); console.log('Received:', message); // If received pong message if (message === 'pong') { clearTimeout(this.heartbeatTimeoutTimer); return } this.wsListener.onMessage(this.ws,message) // Handle other messages } startHeartbeat() { this.heartbeatTimer = setInterval(() => { if (this.ws.readyState === WebSocket.OPEN) { // Send ping message this.ws.send('ping'); // Set timeout for pong response this.heartbeatTimeoutTimer = setTimeout(() => { console.log('Heartbeat timeout'); this.ws.terminate(); }, this.heartbeatTimeout); } }, this.heartbeatInterval); } cleanup() { if (this.heartbeatTimer) { clearInterval(this.heartbeatTimer); this.heartbeatTimer = null; } if (this.heartbeatTimeoutTimer) { clearTimeout(this.heartbeatTimeoutTimer); this.heartbeatTimeoutTimer = null; } if (this.reconnectTimer) { clearTimeout(this.reconnectTimer); this.reconnectTimer = null; } } scheduleReconnect() { if (!this.reconnectTimer) { this.reconnectTimer = setTimeout(() => { console.log('Attempting to reconnect...'); this.connect(); }, this.reconnectDelay); } } close() { this.cleanup(); if (this.ws) { this.ws.close(); } } sendMsg(msg){ if (this.ws) { this.ws.send(msg); } } } module.exports = WebSocketClient;