user3285713
user3285713

Reputation: 151

Continually trying to reconnect until a connection is established

I'm trying to create a routine which does the following

while(true)
{

  cxn = connect(addr);
  if(!cxn)
  {
    sleep(1000);
    continue;
  }
  else
  {
    break;
  }
}

However, due to the asynchronous nature of the NodeJS and the websocket library I am using (ws), it appears that I am forced to use callbacks for detecting a successful connection vs an error. I can't figure out how to adapt this to my algorithm above because the event of a successful connection vs failed is assumed to occur within the loop and not be bound to an asynchronous function.

Here is an example of what I mean to illustrate the point I am trying to make:

while(true)
{

  cxn = connect(addr);
  cxn.on('error', function(error)
  {
    sleep(1000);
    continue; // this is invalid
  });
  cxn.on('connect', function()
  {
    break; // this is invalid
  });
}

As you can see here. Both the continue and break statements are invalid because they occur within the bounds of a callback function which isn't called inside the bounds of a for loop.

How would I go about implementing this desired functionality given the asynchronous design of Node and WS?

**EDIT: ** I have tried to modify my code to make it block until a connection is established. However, I am still unable to get a connection and the program just hangs. I would assume that my while loop is somehow blocking execution of the event loop. Any ideas?

Code:

var WebSocket = require('ws');
var socket = null;

function try_connection(addr)
{
  var connection_status = 'CONNECTING';
  console.log("attempting to connect to web socket server...");
  socket = new WebSocket(addr);
  socket.on('error', function(error)
  {
    if(error.errno == 'ECONNREFUSED')
    {
      console.log('CONNREFUSED');
      debugger;
    }
    else
    {
      console.log('unrecoverable error...');
      process.exit(-1);
    }
  });

  socket.on('open', function()
  {
    console.log('connection opened');
    debugger;
    connection_status = 'CONNECTED';
  });

  while(connection_status != 'CONNECTED')
  {
    setTimeout(100);
    continue;
  }
  return socket;
}

try_connection('ws://127.0.0.1:1337');
console.log('hello world');

Upvotes: 0

Views: 1629

Answers (1)

apsillers
apsillers

Reputation: 115950

This can be done with an asynchronous "recursive" function:

function tryConnecting(callback) {
  var cxn = connect(addr);
  cxn.on('error', function(error) {
    setTimeout(tryConnecting.bind(this, callback), 1000);
  });
  cxn.on('connect', function() {
    callback(cxn);
  });
}

tryConnecting calls itself repeatedly, in one-second intervals (using setTimeout), until the connect() call causes the connect event to fire. When it does, instead of queuing up another setTimeout call to run tryConnecting, the callback function runs with cxn as its argument.

Anything you want to do after the connection completes should go inside of the callback function you pass into tryConnecting.

Upvotes: 1

Related Questions