Autobahn.JS разрывает соединение

У меня есть реализация Crossbar.js, в которой данные отправляются между клиентом (веб-сайтом) и сервером (Node.js) через сервер веб-сокетов Crossbar. Обе стороны используют Autobahn.JS для подключения к серверу Crossbar.

Соединение работает нормально, но кажется, что и клиент, и сервер отключаются и снова подключаются в случайные моменты. Это происходит примерно раз в две минуты. Я также видел, что обрывы связи не происходили одновременно с обеих сторон. Это заставило меня подумать, что проблема заключается в реализации Autobahn, которую я использую с обеих сторон (что примерно одинаково для клиента и сервера).

Ниже показан метод, который я использую для подключения к серверу Crossbar из Node.js. Версия для браузера практически идентична. Я только изменил подписку и изменил переменные const и let на 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);
    }
  }

Я не вижу той части кода, которая содержит ошибки и вызывает разрыв соединения.

Вот что выдает консоль:

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
}

Так как переменная retry_count всегда 1, я думаю, что связь между этими каплями восстанавливается.

Вот что выдает сервер Crossbar:

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"

Поскольку сервер Crossbar может перечислять отключения и подключения, я не думаю, что Crossbar является проблемой.

Я надеюсь, что у кого-то есть понимание, которое поможет мне :)


person Mark    schedule 23.08.2017    source источник


Ответы (1)


На самом деле это не похоже на проблему, связанную с Autobahn.js (или Crossbar.js, если уж на то пошло). Это больше похоже на проблему, связанную с спецификациями тайм-аута браузера или TCP.

Бездействующие соединения могут быть разорваны в какой-то момент. Похоже, что какое-то программное обеспечение или устройство, участвующее в этом подключении, определило, что оно слишком долго не используется, и поэтому закрыло его. Обычно это хорошо; вы не хотите, чтобы мертвые соединения простаивали целыми днями, и именно так был разработан TCP.

Теперь поговорим о решениях. Это довольно просто, на самом деле. Вы хотели бы поддерживать соединение, отправляя какое-то сообщение каждые X секунд. Отправляя, например, пульсацию или эхо-запрос каждые 30 секунд, вы избавите браузер, клиентскую или серверную ОС и любые другие промежуточные устройства от прерывания соединения из-за слишком долгого бездействия.

Если вы хотите быть абсолютно уверены, что соединение прерывается из-за слишком долгого бездействия, вы можете взглянуть на Wireshark. Взглянув на необработанные пакеты, которые на самом деле отправляются по сети, вы быстро найдете точную причину их прерывания.

person Robbietjuh    schedule 23.08.2017