socket.io:断开连接事件 - “传输关闭”、“客户端命名空间断开连接”、“传输错误”和“强制关闭”
socket.io: Disconnect event - 'transport close', 'client namespace disconnect', 'transport error' and 'forced close'
socket.io v1.2.1(仅使用"轮询"传输),有时我的客户端会遇到断开连接。
大约 50% 的时间我会ping timeout
我的断开连接事件回调函数,这是合理的。
其他时候,我会得到transport close
,client namespace disconnect
,transport error
和forced close
。我在文档中没有找到任何对这些断开连接原因的引用,并且无法从代码中真正理解它们的含义。
我想确保我以最佳方式处理每次断开连接(也许可以防止它们)。
也许有人可以稍微阐明这些原因。
没有文档,这或多或少是我可以从代码中解释的:
Forced close
- 套接字处于关闭状态
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();
};
关闭的交通工具(此处无原因)
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");
}
我们收到客户端断开连接数据包,因此我们将套接字状态更改为"关闭"
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');
};
交通便利的原因之一
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
/**
* 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);
}
};
似乎他们从任何地方向套接字抛出错误,因此找到原因的唯一方法是阅读错误描述(不要太多信息)或查看其所有库以查找导致错误的原因。
PD:有很多错误。
在服务器端尝试此代码
var fs = require('fs');
var pkey = fs.readFileSync('/etc/ssl/private/ssl.key'); //Replace the path of your SSL key
var pcert = fs.readFileSync('/etc/ssl/certs/ssl.crt');//Replace the path of your SSL cert
var options = {
key: pkey,
cert: pcert
};
var app = require('https').createServer(options);
var io = require('socket.io')(app, {'pingTimeout': 180000, 'pingInterval': 25000});
这里pingInterval
很重要,保持低调,我尝试了各种值,发现 25 秒可以很好地在超时之前保持套接字不断 ping。
主要问题是,如果在 60 秒内没有 ping/pong,那么它将断开连接并尝试自动重新连接。 另外,我发现服务器端pingTimeout
超时,客户端无法帮助在 60 秒内断开套接字。这是由于chrome最新版本83而发生的。
我遇到过类似的情况,从服务器到客户端的更新过多(几秒钟内大约 2000 次)似乎会导致连接被强制关闭。较少发送更新可以解决问题。
我还没有机会找出这是由 socket.io 本身还是某些防火墙/服务器机制引起的。也许是因为淹没服务器和客户端之间的连接会弄乱心跳机制,尽管客户端日志没有显示这一点。
虽然目前还没有找到确切的原因,但也许这可以为一些人指明正确的方向来找到解决方案。
这可能会发生。有时,当我不幸要处理时,这是由于我,服务器和其他客户端之间的防火墙。
对于 ping 超时,您可以尝试增加服务器端的 ping 间隔
io = require( 'socket.io' )( httpServer, { pingInterval: 60000 } );
- cordova图像上传出现文件传输错误
- socket.io:断开连接事件 - “传输关闭”、“客户端命名空间断开连接”、“传输错误”和“强制关闭”
- AJAX Http POST:没有传输错误
- 多个chrome.runtime.onMessage-Listeners-断开连接的端口错误
- 传输轮询错误,Socket.Io
- 在 cordova 项目中,我正在使用文件传输插件上传个人资料照片,它总是返回代码 1 错误
- 科尔多瓦的文件传输写入错误(代码 1)
- 角度$asyncValidators将错误代码传输到模板
- 尽管成功传输了 json,但我的 Jquery.ajax 方法在响应中获得了错误状态
- JavaScript 错误:“调用的对象已与其客户端断开连接”在 IE8 中的 window.open 上
- 从文件流式传输、转换和 postgres 错误
- Chrome错误-资源被解释为脚本,但使用MIME类型text/plain传输
- Javascript错误“;被调用的对象已与其客户端断开连接”;创建ActiveXObject时
- Bower - EPERM,断开链接错误
- Websocket通过wss://断开连接,没有任何错误
- 使用phonegap传输图像到php时出现错误
- 如何捕获条带传输的错误和成功?
- 套接字.错误的请求,响应{"代码":0,"消息";传输未知"}
- Php mysql未定义索引错误使用jquery从一个页面传输数据到另一个页面
- PhoneGap文件传输错误1,在哪里写FileTransfers