javascriptnode.jsautobahncrossbar

Autobahn.JS drops connection


I've got a Crossbar.js implementation where data is send between client (website) and server (Node.js) over a Crossbar websocket server. Both sides use Autobahn.JS to connect to the Crossbar server.

The connection works fine, but it seems that both the client and server disconnect and reconnect at random moments. This happens about once per two minutes. I also saw that the connection drops did not happen at the same time at both sides. This made me think that the problem is on the Autobahn implementation I use at both sides (which is about the same for client and server).

Below is the method I use to connect to the Crossbar server from Node.js. The version for the browser is almost identical. I only changed the subscription and changed the const and let variables to var.

  start(connectionConfig) {
    const self = this;

    self.host = connectionConfig.host;
    self.realm = connectionConfig.realm;
    self.channelPrefix = connectionConfig.channelPrefix;

    try {

      // Start an Autobahn websocket connection
      self.connection = new autobahn.Connection({"url": self.host, "realm": self.realm});
      self.connection.onopen = function(session) {

        // Save session in class
        self.session = session;

        // Listen for incoming commands
        session.subscribe(self.channelPrefix + 'smdc-server', self.onCommand.bind(self));

        // Copy the class variable buffer to a local variable and set the
        // class variable buffer to an empty array.
        let localBuffer = self.socketBuffer;
        self.socketBuffer = [];

        // Send all messages from the local buffer that were 'send' using the class method (not displayed here on StackOverflow) while the connection was not yet established.
        for (var i = 0; i < localBuffer.length; i++) {
          session.publish(localBuffer[i].channel, [localBuffer[i].data]);
        }
      }

      self.connection.onclose = function(reason, details) {
        console.log("Autobahn closed!");
        console.log("Reason: ");
        console.log(reason);
        console.log("Details: ");
        console.log(details);

        self.session = null;
      }

      self.connection.open();
    } catch (err) {
      console.log(err);
    }
  }

I can't see the part in the code that bugs and causes the connection drop.

This is what the console outputs:

Autobahn closed!
Reason: 
lost
Details: 
{
    reason: null, 
    message: null, 
    retry_delay: 1.4128745255660942, 
    retry_count: 1, 
    will_retry: true
}

Autobahn closed!
Reason: 
lost
Details: 
{
    reason: null, 
    message: null, 
    retry_delay: 1.2303848117273903, 
    retry_count: 1, 
    will_retry: true
}

Since the retry_count variable is always 1, I think the connection is restored between these drops.

This is what the Crossbar server outputs:

2017-08-23T10:46:34+0200 [Router      10622] session "1355162039012002" left realm "SMDC"
2017-08-23T10:46:35+0200 [Router      10622] session "2006451409833362" joined realm "SMDC"
2017-08-23T10:46:37+0200 [Router      10622] session "2006451409833362" left realm "SMDC"
2017-08-23T10:46:37+0200 [Router      10622] session "224071819838749" joined realm "SMDC"

Since the Crossbar server is able to list the disconnections and connections, I don't think Crossbar is the problem.

I hope someone has the insight that helps me :)


Solution

  • This does not really sound like a problem that has to do with Autobahn.js (or Crossbar.js for that matter). It seems more like a problem having to do with the browser or TCP timeout specs.

    Idle connections might get terminated at some point. It seems like some software or device involved in this connection has determined it to be idle for too long and therefor closing it. Normally that's a good thing; you don't want dead connections to be idle for days on end and it's actually how TCP was designed.

    Now, let's talk solutions. It's pretty simple, actually. You'd want to keep the connection alive by sending some kind of a message every X seconds. By sending a heartbeat or a ping every 30 seconds, for example, you'd eliminate the browser, client or server OS and any other devices in between from terminating the connection due to it being idle for too long.

    In case you want to be absolutely sure it's the connection getting terminated for being idle for too long, you might want to have a look at Wireshark. By having a look at the raw packets that actually get sent over the wire you'll quickly find the exact reasoning for it getting terminated.