pladaria / reconnecting-websocket

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

Doesn't work for GDAX (node) #48

Closed Bomper closed 6 years ago

Bomper commented 6 years ago

The module doesn't manage to stay connected to the [GDAX] crypto data feed:

const WebSocket = require('ws');
const ReconnectingWebSocket = require('reconnecting-websocket');
const rws = new ReconnectingWebSocket('wss://ws-feed.gdax.com', [], {
  constructor: WebSocket,
  debug: true,
});

let lastPointTimestamp = new Date();
setInterval(() => {
  if (Date.now() - lastPointTimestamp > 60 * 1000)
    // No data in the past minute since we got called
    console.warn('Got disconnected and did not reconnect');
}, 60 * 1000);

function handleData(data) {
  lastPointTimestamp = Date.now();
  console.log(data.price);
}

rws.on('open', () => {
  rws.send(JSON.stringify({
    type: 'subscribe',
    product_ids: ['BTC-USD'],
    channels: ['matches'],
  }));
});
rws.on('message', data => handleData(JSON.parse(data)));
rws.on('error', err => {
  console.error('ON ERROR -', err);
});

The log shows this:

ON ERROR - { Error: read ECONNRESET
    at _errnoException (util.js:1003:13)
    at TLSWrap.onread (net.js:620:25) errno: 'ECONNRESET', code: 'ECONNRESET', syscall: 'read' }
RWS: handleClose { shouldRetry: true }
RWS: retries count: 1
RWS: handleClose - reconnectDelay: 2043.1049894719274
RWS: connect
RWS: bypass properties
RWS: timeout
kinsi55 commented 6 years ago

I have exactly the same issue with Twitch PubSub.

RWS: handleClose { shouldRetry: true }
RWS: retries count: 1
RWS: handleClose - reconnectDelay: 2125.6480950789783
RWS: connect
RWS: bypass properties
RWS: timeout

Edit: Looks like i've found the Culprit. In the connect function, a handler for 'close' is created which calls the handleClose function, which then tries to reconnect by calling connect after a delay. The issue is that the connect function has a timeout delay which does not try to reconnect upon timeout, thus it stalls. Lemme whip up a fix.

pladaria commented 6 years ago

Please, don't use ws as Websocket constructor. Use the wrapper module html5-websocket as documented in the README: https://github.com/pladaria/reconnecting-websocket#using-alternative-constructor

The way ws frees resources seems to be incompatible with this library. This may change in the future, I'm planning a full rewrite.

Bomper commented 6 years ago

Just wanted to note that using Html5WebSocket isn't a drop-in replacement for WebSocket. Neither .on('open'), nor .onopen works.

const ReconnectingWebSocket = require('reconnecting-websocket');
const rws = new ReconnectingWebSocket('wss://ws-feed.gdax.com', [], {
  constructor: Html5WebSocket,
  debug: true,
});

rws.onopen(() => {            // <-- TypeError: rws.onopen is not a function
  rws.send(JSON.stringify({
    type: 'subscribe',
    product_ids: ['BTC-USD'],
    channels: ['matches'],
  }));
});

I had to convert my code to use .addEventListener.

However, the connection to GDAX now does reconnect automatically, so thanks for the module! :raised_hands:

pladaria commented 6 years ago

Happy to hear that!

ReconnectingWebsocket uses the standard WebSocket API

you can use .addEventListener or assign a function to onopen: rws.onopen = () => console.log('open');

geekbleek commented 6 years ago

The URL posted above appears to no longer have a section on alternate constructors: https://github.com/pladaria/reconnecting-websocket#using-alternative-constructor Can you provide guidance on the best constructor for serverside usage in node.js?