我有一个使用xhr作为唯一传输的socket.io连接。当我在浏览器中加载应用程序(经过chrome和ff测试)时,套接字可以连接,并且一切正常,直到我离开页面为止。如果重新加载浏览器,则可以看到客户端发出了“断开连接”事件,但是服务器断开连接事件在很长一段时间内不会触发(可能是客户端心跳超时)。这是一个问题,因为当客户端断开连接时,我会在服务器中进行一些清理工作。如果客户端重新加载,则在触发断开连接之前会收到多个连接事件。我也尝试在窗口的“ beforeunload”事件中手动从客户端发出断开连接消息,但无济于事。有任何想法吗?
我调试了socket.io服务器,并且可以确认Manager.prototype.onClientDisconnect仅由于“关闭超时”原因而受到攻击。
经过更多调试后,我注意到socket.io Manager对象中的以下配置:
blacklist : ['disconnect']
这导致namespace.js中的该分支无法处理事件:
case 'event': // check if the emitted event is not blacklisted if (-~manager.get('blacklist').indexOf(packet.name)) { this.log.debug('ignoring blacklisted event `' + packet.name + '`'); } else { var params = [packet.name].concat(packet.args); if (dataAck) { params.push(ack); } socket.$emit.apply(socket, params); }
此拉取请求https://github.com/LearnBoost/socket.io/pull/569中详细介绍了更改。我了解XHR为何要这样做,因为任何人都可以发送带有随机会话ID的HTTP请求,以尝试断开其他用户与服务器的连接。
相反,我打算做的是检查每个新连接中服务器中现有的会话ID,并确保在继续连接逻辑之前运行我的断开逻辑。