WebSocketClient.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. const WebSocket = require('ws');
  2. class WebSocketClient {
  3. constructor(url, options = {},wsListener) {
  4. this.url = url;
  5. this.options = options;
  6. this.wsListener = wsListener
  7. this.reconnectDelay = options.reconnectDelay || 5000;
  8. this.heartbeatInterval = options.heartbeatInterval || 30000;
  9. this.heartbeatTimeout = options.heartbeatTimeout || 5000;
  10. this.ws = null;
  11. this.heartbeatTimer = null;
  12. this.reconnectTimer = null;
  13. this.heartbeatTimeoutTimer = null;
  14. this.connect();
  15. }
  16. connect() {
  17. try {
  18. this.ws = new WebSocket(this.url);
  19. this.ws.on('open', () => {
  20. console.log('WebSocket connected');
  21. this.startHeartbeat();
  22. this.wsListener.onOpen(this.ws)
  23. });
  24. this.ws.on('message', (data) => {
  25. this.handleMessage(data);
  26. });
  27. this.ws.on('close', () => {
  28. console.log('WebSocket closed');
  29. this.cleanup();
  30. this.scheduleReconnect();
  31. this.wsListener.onClosing()
  32. });
  33. this.ws.on('error', (error) => {
  34. console.error('WebSocket error:', error);
  35. this.cleanup();
  36. this.scheduleReconnect();
  37. this.wsListener.onFailure()
  38. });
  39. } catch (error) {
  40. console.error('Connection error:', error);
  41. this.scheduleReconnect();
  42. this.wsListener.onFailure()
  43. }
  44. }
  45. handleMessage(data) {
  46. // Handle incoming messages
  47. const message = data.toString();
  48. console.log('Received:', message);
  49. // If received pong message
  50. if (message === 'pong') {
  51. clearTimeout(this.heartbeatTimeoutTimer);
  52. return
  53. }
  54. this.wsListener.onMessage(this.ws,message)
  55. // Handle other messages
  56. }
  57. startHeartbeat() {
  58. this.heartbeatTimer = setInterval(() => {
  59. if (this.ws.readyState === WebSocket.OPEN) {
  60. // Send ping message
  61. this.ws.send('ping');
  62. // Set timeout for pong response
  63. this.heartbeatTimeoutTimer = setTimeout(() => {
  64. console.log('Heartbeat timeout');
  65. this.ws.terminate();
  66. }, this.heartbeatTimeout);
  67. }
  68. }, this.heartbeatInterval);
  69. }
  70. cleanup() {
  71. if (this.heartbeatTimer) {
  72. clearInterval(this.heartbeatTimer);
  73. this.heartbeatTimer = null;
  74. }
  75. if (this.heartbeatTimeoutTimer) {
  76. clearTimeout(this.heartbeatTimeoutTimer);
  77. this.heartbeatTimeoutTimer = null;
  78. }
  79. if (this.reconnectTimer) {
  80. clearTimeout(this.reconnectTimer);
  81. this.reconnectTimer = null;
  82. }
  83. }
  84. scheduleReconnect() {
  85. if (!this.reconnectTimer) {
  86. this.reconnectTimer = setTimeout(() => {
  87. console.log('Attempting to reconnect...');
  88. this.connect();
  89. }, this.reconnectDelay);
  90. }
  91. }
  92. close() {
  93. this.cleanup();
  94. if (this.ws) {
  95. this.ws.close();
  96. }
  97. }
  98. sendMsg(msg){
  99. if (this.ws) {
  100. this.ws.send(msg);
  101. }
  102. }
  103. }
  104. module.exports = WebSocketClient;