socket.io:断开事件 – “传输closures”,“客户端命名空间断开连接”,“传输错误”和“强制closures”

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

大概有50%的时间我在我的断开事件callback函数上得到了ping timeout ,这是合理的。

其他时候,我得到transport closeclient namespace disconnecttransport errorforced close 。 我没有发现文档中那些断开连接的原因,也没有从代码中真正理解它们的含义。

我想确保我处理每个断开连接的最佳方式(也许阻止它们)。

也许有人可以对这些理由说一点点。

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

Forced close – 套接字处于closures状态

Forced closehttps://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(); }; 

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

Transport closehttps://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"); } 

我们得到一个客户端断开包,所以我们改变套接字状态为“closures”

Client namespace disconnecthttps://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'); }; 

交通接近的原因之一

Transport errorhttps://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

 /** * 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); } }; 

看起来他们把错误扔给了任何地方的套接字,所以find原因的唯一方法是通过阅读错误描述(不要太多的信息)或查看所有的库来找出造成错误的原因。

PD:有很多错误。

不幸的是这可能发生。 有时候,我不幸遇到这个问题,这是由于我之间,服务器和其他客户端之间的防火墙。

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

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