123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- 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;
|