0

So, I have a Express NodeJS server that is making a connection with another app via an upagraded WebSocket uri for a data feed. If this app goes down, then obviously the WebSocket connection gets closed. I need to reconnect with this uri once the app comes back online.

My first approach was to use a while loop in the socket.onclose function to keep attempting to make the re-connection once the app comes back online, but this didn't seem to work as planned. My code looks like this:

socket.onclose = function(){
    while(socket.readyState != 1){
        try{
            socket = new WebSocket("URI");
            console.log("connection status: " + socket.readyState);
        }
        catch(err) {
            //send message to console
        }
    }
};

This approach keeps giving me a socket.readyState of 0, even after the app the URI is accessing is back online.

Another approach I took was to use the JavaScript setTimout function to attempt to make the connection by using an exponential backoff algorithm. Using this approach, my code in the socket.onclose function looks like this:

socket.onclose = function(){
    var time = generateInterval(reconnAttempts); //generateInterval generates the random time based on the exponential backoff algorithm
    setTimeout(function(){
        reconnAttempts++; //another attempt so increment reconnAttempts
        socket = new WebSocket("URI");
    }, time);
};

The problem with this attempt is that if the app is still offline when the socket connection is attempted, I get the following error, for obvious reasons, and the node script terminates:

events.js:85
    throw er; // Unhandled 'error' event
Error: connect ECONNREFUSED
    at exports._errnoException (util.js:746:11)
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1010:19)

I also began using the forever node module to ensure that my node script is always running and to make sure it gets restarted after an unexpected exit. Even though I'm using forever, after a few restarts, forever just stops the script anyway.

I am basically just looking for a way to make my NodeJS server more robust and automatically re-connect with another server that may have gone down for some reason, instead of having to manually restart the node script.

Am I completely off base with my attempts? I am a noob when it comes to NodeJS so it may even be something stupid that I'm overlooking, but I have been researching this for a day or so now and all of my attempts don't seem to work as planned.

Any suggestions would be greatly appreciated! Thanks!

Mr Shantastic
  • 510
  • 1
  • 7
  • 16
  • This might, of course, not be appropriate for your use case but if you're willing to migrate your code to a plugin, I have nothing but good experiences with [socket.io](http://socket.io/) which has solid reconnection in my experience. Abstracting websocket connections away to a plugin is the way to do it IMO. You can see how to connect two node servers [here](http://stackoverflow.com/questions/8837236/how-to-connect-two-node-js-servers-with-websockets) – Jack Guy Sep 09 '15 at 15:37
  • try to use an error handler maybe that can help https://www.joyent.com/developers/node/design/errors – nada Sep 09 '15 at 16:04

1 Answers1

2

Few suggestions

1) Start using domain which prevents your app from an unexpected termination. Ie your app will run under the domain(run method of domain). You can implement some alert mechanism such as email or sms to which will notify when any error occurs.

2) Start using socket.io for websocket communication, it automatically handles the reconnection. Socket.io uses keep-alive heartbeat and continuously polls from the server.

3) Start using pm2 instead of forever. Pm2 allows clustering for your app which improves the performance.

I think this may improve your app's performance, stability and robustness.

  • Thanks for the suggestions Hitesh. Just a couple things: – Mr Shantastic Sep 09 '15 at 18:54
  • Thanks for the suggestions Hitesh. Just a couple things: 1) I had the understanding that domain was being deprecated... https://nodejs.org/api/domain.html 2) I am currently using socket.io for the client to node server connection. It appeared that WebSocket provided an easier way to make a connection to an upgraded uri such as ws://localhost/bla/bla to grab live data from a data stream. Then I was sending appropriate messages to the client via socket.io. I'll have to do some more research into socket.io on how to do the same. 3) Reading up on pm2. I'll probably make the switch like you suggest – Mr Shantastic Sep 09 '15 at 19:01
  • Please check https://github.com/nodejs/node/issues/66, as you can see the discussion is going on since last 9 months. On the domain module page it says it is pending deprecation till any alternative comes. Once any alternative come, it would be easy to integrate instead of domain. Till that time you may save your unexpected crashes. Or you can listen to uncaughtException of process(http://www.howtojs.org/understanding-exceptions-domains-in-nodejs/) – Hitesh Chapanera Sep 09 '15 at 19:54
  • Thanks again Hitesh! I guess domains are the way to go, I'll begin researching them. Thanks for the helpful information/links. Once I get a functional solution I'll update my question. – Mr Shantastic Sep 11 '15 at 13:15