javascript socket.io:断开连接事件 - “传输关闭”、“客户端命名空间断开”、“传输错误”和“强制关闭”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29073746/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 10:03:26  来源:igfitidea点击:

socket.io: Disconnect event - 'transport close', 'client namespace disconnect', 'transport error' and 'forced close'

javascriptnode.jshtmlsocket.io

提问by Gilad Artzi

Using socket.io v1.2.1 (only using the "polling" transport), sometimes my clients experience disconnections.

使用 socket.io v1.2.1(仅使用“轮询”传输),有时我的客户会遇到断开连接的情况。

About 50% of the time I get ping timeouton my disconnect event callback function, which is reasonable.

我大约有 50% 的时间ping timeout使用了断开连接事件回调函数,这是合理的。

Other times, I get transport close, client namespace disconnect, transport errorand forced close. I did not find any reference to those disconnection reasons in the documentation, and was not able to really understand their meaning from the code.

其他时候,我得到transport close, client namespace disconnect,transport errorforced close。我在文档中没有找到对这些断开连接原因的任何参考,并且无法从代码中真正理解它们的含义。

I want to make sure I handle each disconnection the best way (and maybe prevent them).

我想确保我以最好的方式处理每次断开连接(并可能防止它们)。

Maybe someone can shed a little light about these reasons.

也许有人可以对这些原因有所了解。

回答by Jairo

There is no documentation, this is more or less what i can interpret from the code:

没有文档,这或多或少是我可以从代码中解释的:

Forced close- The socket is in closing state

Forced close- 套接字处于关闭状态

Forced close- https://github.com/socketio/engine.io/blob/master/lib/socket.js

Forced close- https://github.com/socketio/engine.io/blob/master/lib/socket.js

function onPacket(packet){
    if ('ping' == packet.type && 'probe' == packet.data) {
      transport.send([{ type: 'pong', data: 'probe' }]);
      self.emit('upgrading', transport);
      clearInterval(self.checkIntervalTimer);
      self.checkIntervalTimer = setInterval(check, 100);
    } else if ('upgrade' == packet.type && self.readyState != 'closed') {
      debug('got upgrade packet - upgrading');
      cleanup();
      self.upgraded = true;
      self.clearTransport();
      self.setTransport(transport);
      self.emit('upgrade', transport);
      self.setPingTimeout();
      self.flush();
      if (self.readyState == 'closing') {
        transport.close(function () {
          self.onClose('forced close');
        });
      }
    } else {
      cleanup();
      transport.close();
    }
  }


Socket.prototype.close = function () {
  if ('open' != this.readyState) return;

  this.readyState = 'closing';

  if (this.writeBuffer.length) {
    this.once('drain', this.closeTransport.bind(this));
    return;
  }

  this.closeTransport();
};

The transport where closed (no reason here)

关闭的交通工具(这里没有理由)

Transport close- https://github.com/socketio/engine.io/blob/master/lib/socket.js

Transport close- https://github.com/socketio/engine.io/blob/master/lib/socket.js

 function cleanup() {
    self.upgrading = false;

    clearInterval(self.checkIntervalTimer);
    self.checkIntervalTimer = null;

    clearTimeout(self.upgradeTimeoutTimer);
    self.upgradeTimeoutTimer = null;

    transport.removeListener('packet', onPacket);
    transport.removeListener('close', onTransportClose);
    transport.removeListener('error', onError);
    self.removeListener('close', onClose);
  }


  function onTransportClose(){
    onError("transport closed");
  }

We got a client disconnect packet, so we change socket state to 'closing'

我们得到了一个客户端断开数据包,因此我们将套接字状态更改为“关闭”

Client namespace disconnect- https://github.com/socketio/socket.io/blob/master/lib/socket.js

Client namespace disconnect- https://github.com/socketio/socket.io/blob/master/lib/socket.js

Socket.prototype.onpacket = function(packet){
  debug('got packet %j', packet);
  switch (packet.type) {
    case parser.EVENT:
      this.onevent(packet);
      break;

    case parser.BINARY_EVENT:
      this.onevent(packet);
      break;

    case parser.ACK:
      this.onack(packet);
      break;

    case parser.BINARY_ACK:
      this.onack(packet);
      break;

    case parser.DISCONNECT:
      this.ondisconnect();
      break;

    case parser.ERROR:
      this.emit('error', packet.data);
  }
};


Socket.prototype.ondisconnect = function(){
  debug('got disconnect packet');
  this.onclose('client namespace disconnect');
};

One of the reasons of transport close

交通封闭的原因之一

Transport error- https://github.com/socketio/engine.io/blob/master/lib/socket.js

Transport error- https://github.com/socketio/engine.io/blob/master/lib/socket.js

/**
 * Called upon transport error.
 *
 * @param {Error} error object
 * @api private
 */

Socket.prototype.onError = function (err) {
  debug('transport error');
  this.onClose('transport error', err);
};

https://github.com/socketio/engine.io/blob/master/lib/transport.js

https://github.com/socketio/engine.io/blob/master/lib/transport.js

/**
 * Called with a transport error.
 *
 * @param {String} message error
 * @param {Object} error description
 * @api private
 */

Transport.prototype.onError = function (msg, desc) {
  if (this.listeners('error').length) {
    var err = new Error(msg);
    err.type = 'TransportError';
    err.description = desc;
    this.emit('error', err);
  } else {
    debug('ignored transport error %s (%s)', msg, desc);
  }
};

It seems like they throw errors to sockets from everywhere, so the only way of find the cause is by reading the error description (not too much information) or looking all their libraries to find what is causing the error.

似乎他们从任何地方向套接字抛出错误,所以找到原因的唯一方法是阅读错误描述(不要太多信息)或查看他们的所有库以找出导致错误的原因。

PD: there are a lot of errors.

PD:有很多错误。

回答by kaytrance

Unfortunately this may happen. Sometimes, as I had misfortune to deal with, it was due to firewall somewhere in between me, server and other client.

不幸的是,这可能会发生。有时,由于我有不幸要处理,这是由于我、服务器和其他客户端之间的防火墙。

For ping timeouts you may try to increase ping interval on server side

对于 ping 超时,您可以尝试增加服务器端的 ping 间隔

io = require( 'socket.io' )( httpServer, { pingInterval: 60000 } );