pladaria / reconnecting-websocket

Reconnecting WebSocket. For Web, React Native, cli (Node.js)
MIT License
1.23k stars 199 forks source link

WebSocket was closed before the connection was established #183

Open 0xd8d opened 2 years ago

0xd8d commented 2 years ago

This error happens when it tries to reconnect. How can I solve it?

kzay commented 2 years ago

I have exactly the same behaviour

mayurkasar0613 commented 2 years ago

same issue i am also facing.

htotoo commented 1 year ago

Also has the problem. Edited the connect timeout hides the problem, but it is not a solution, since it would crash then too. Would be great if the event would be handled.

barlock commented 1 year ago

After inspecting the code, I'm honestly not sure why the error isn't handled but I've found a decent workaround for my use case.

I'm expecting that a WS endpoint might be down, so I need a way to gracefully time it out and keep retrying. using ws ClientOptions handshakeTimeout will let ws handle the timeout rather than ReconnectiongWebSocket which will throw and crash.

This PR should give us the ability to pass in options, but until then:

import ReconnectingWebSocket from 'reconnecting-websocket';
import { type Options, type UrlProvider } from 'reconnecting-websocket';
import WebSocket, { type ClientOptions } from 'ws';

const wsFactory = (options: ClientOptions) =>
  class WsOptions extends WebSocket {
    constructor(url: string, protocols?: string | string[]) {
      super(url, protocols, options);
    }
  };

export class KeepAliveWs extends ReconnectingWebSocket {
  constructor(
    url: UrlProvider,
    protocols?: string | string[],
    options: Options = {},
  ) {
    const { connectionTimeout = 4000 } = options;
    const opts = {
      ...options,
      connectionTimeout: connectionTimeout + 1000, // give WS time to disconnect without throwing
      WebSocket: wsFactory({ handshakeTimeout: connectionTimeout }),
    };

    super(url, protocols, opts);
  }
}
ondrejFuchs commented 1 year ago

Hi,

I have the same problem with ws.reconnect() function, when Iam getting:

subscribeMatchEvents, Close ws connection
node:events:495
throw er; // Unhandled 'error' event
^
{}
Error: WebSocket was closed before the connection was established at WebSocket.close (/home/node/node_modules/ws/lib/websocket.js:285:14) at ReconnectingWebSocket._disconnect (/home/node/node_modules/reconnecting-websocket/dist/reconnecting-websocket-cjs.js:539:22) at ReconnectingWebSocket._handleError (/home/node/node_modules/reconnecting-websocket/dist/reconnecting-websocket-cjs.js:180:19) at ReconnectingWebSocket._handleTimeout (/home/node/node_modules/reconnecting-websocket/dist/reconnecting-websocket-cjs.js:529:14) at Timeout.<anonymous> (/home/node/node_modules/reconnecting-websocket/dist/reconnecting-websocket-cjs.js:524:75) at listOnTimeout (node:internal/timers:569:17) at process.processTimers (node:internal/timers:512:7)
Emitted 'error' event on WebSocket instance at:
at emitErrorAndClose (/home/node/node_modules/ws/lib/websocket.js:984:13)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
{}

I tried to update the code based on https://github.com/pladaria/reconnecting-websocket/pull/193, but error remain the same.

My WS options are:

const wsOptions = {
    WebSocket: WS,
    connectionTimeout: 1000,
    maxRetries: 10,
    startClosed: true
};

Also I noticed it happened when i receive close event:

ws.addEventListener('close', () => {
  ws.onclose = () => {
      logger.info('subscribeMatchEvents, Close ws connection');
  };
});

Versions used:

Adding more from the logs:

RWS> timeout event
RWS> error event TIMEOUT
RWS> removeListeners
RWS> close event
RWS> connect 1
RWS> removeListeners
RWS> next delay 4620.82810338248
RWS> exec error listeners

Any thoughts?