vitalets/websocket-as-promised

Add support for auto reconnect

Closed this issue · 4 comments

ivosh commented

It would be nice of websocket-as-promised had a support for auto-reconnect in case of the underlying websocket disconnect.
There are actually two use cases:

  • Reconnect after the underlying websocket got disconnected
  • Keep trying reconnect if the first initial connect attempt failed

I envision a need for the following configuration options:

  • reconnectInterval [ms]
  • reconnectAttempts
  • reconnectDecay (eventually)

The task sounds reasonable.
I decided to search for separate projects implementing WebSocket reconnect feature and found several ones:

I see that they offer many other interesting options. For example, detecting network online/offline status and so on. I think the best solution is to keep this feature separated and use with websocket-as-promised via custom constructor:

import WebSocketAsPromised from 'websocket-as-promised';
import ReconnectingWebSocket from 'reconnecting-websocket';

const wsp = new WebSocketAsPromised(wsUrl, {
  createWebSocket: url => new ReconnectingWebSocket(url)
});

I would appreciate if you try it and share the feedback.

ivosh commented

Thank you for sharing your thoughts.

Currently I need just an indefinite connect retry together with queuing requests until websocket becomes connected. So I ended up with just:

const wsp = new WebSocketAsPromised(url, {
  createWebSocket: url => new WebSocket(url),
  ...});
wsp.onClose.addListener(this.retryConnect);

Requests are queued through a Channel instance which is unmuted upon websocket connect and muted with accumulation upon websocket close.

Should I need more sophisticated retry control, I will try one of your suggestions.

Looks like simple and pretty solution! You are welcome :)

The task sounds reasonable. I decided to search for separate projects implementing WebSocket reconnect feature and found several ones:

I see that they offer many other interesting options. For example, detecting network online/offline status and so on. I think the best solution is to keep this feature separated and use with websocket-as-promised via custom constructor:

import WebSocketAsPromised from 'websocket-as-promised';
import ReconnectingWebSocket from 'reconnecting-websocket';

const wsp = new WebSocketAsPromised(wsUrl, {
  createWebSocket: url => new ReconnectingWebSocket(url)
});

I would appreciate if you try it and share the feedback.

According to this demo, pladaria's reconnecting-websocket seems not fit..

If Reconnecting timeout occurs, RecWS will call close first, then WSP will call _cleanUp, pointer _ws within WSP will be set to null.. If then reconnecting succeed, the open which set _ws for WSP correctly must called mannually.

In the same time, open will recall createWebSocket, if you dont want to create duplicate RecWS instances, the singleton logic should be done mannually.

Kind like this

const wsp = new WebSocketP(url, { createWebSocket: (url) => {
  if (!saver) {
      saver = new ReconnectingWebSocket(url);
  }
  saver.addEventListener('open', () => wsp.open())
  return saver;
} });