skip to Main Content

I’m having problems to reconnect to a websocket after the stream is interrupted.

I do not know the root cause why ths stream of data is interrupted. My VPS server is up and running at all time, i have internet access to it, there is another program that runs at the same time and does not have network issues.

But for each packet received I increment my counter i, and if i has not changed for more than 20 seconds, then I try to reconnect. But any code attempts have failed so far, it just loops and tries to reconnect.

Nodejs running on decent linux server. Memory or CPU usage at the time of disconnect is fine. Disconnections have no pattern, sometimes runs for 2 days without problems, sometimes disconnect 4 times per day. When the stream stops, the only way to restart is to exit my code and run it again, and it works immediately, so no problem on server side.

My reconnect code that runs every 20 sec (which is the same as my initial connect code, except for the extra line: const WebSocket = require(‘ws’);

//catch broken stream, if i is not changing, close and reconnect and alert through Telegram
if (i == prev_i) {
    ws.terminate();
    setTimeout(function() {
        console.log('waiting to reconnect');
        const ws = new WebSocket('wss://streamer.cryptocompare.com/v2?api_key=6f56....fe10');
        ws.on('open', function open() {
        ws.send('{"action": "SubAdd","subs": ["0~coineal~BTC~USDT"]}');
        });
    }, 10000);


    console.log("Reconnecting to stream");
    var strMessage = "Reconnecting to stream"
    var message = "chat_id=" + strChatId + "&text=" + strMessage
    var request = require('request');
    request.post({
      headers: {'content-type' : 'application/x-www-form-urlencoded'},
      url:     Url,
      body:    message
    }, function(error, response, body){
    });
}
prev_i = i;

edit 5.5.2020:
as per suggestion below, I’ve modified my code above from

const ws = new WebSocket(...

to

ws = new WebSocket(...

Today the stream dropped for the first time since the change. Unfortunately, instead of trying to reconnect in a loop like before, the code execution stopped with the console messages in attached picture. Line 120 is the line that I modified.
enter image description here

2

Answers


  1. I see one problem with your code: the ws variable is shadowed.

    When you do ws.terminate() your are terminating the socket held by the ws variable in the scope that is in effect around the block of code you quoted. However, in the code you pass to setTimeout to create a new socket you do const ws = new WebSocket(...]. When you do this, you declare a new variable in the scope created by the anonymous function you pass to setTimeout. This variable has the same name as the one in the outer scope but is different from the one in the outer scope. When you assign to it, the outer scope ws is not affected. So the new socket is created, opened and then your code forgets it. So yes, your code will try reconnecting again.

    Just dropping the const and using ws = new WebSocket(...) should work. Obviously, for this to work the ws variable defined in the outer scope cannot be declared with const ws. It has to be declared with let ws, or, not as good, var ws.

    I would also recommend generally using a linter like eslint configured with a sensible set of rules. eslint has rules to report shadowed variables and prevent shadowing errors.

    I would furthermore recommend using something like PWS rather than try to roll your own reconnection code. There are all kinds of edge cases with reconnecting sockets.

    Login or Signup to reply.
  2. Might I suggest using a protocol on top of websockets? This will give you more freedom from these errors and ensure quality of service. One such protocol is MQTT.

    https://www.npmjs.com/package/mqtt
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search