我发现 Chrome 和 Firefox 中的 WebSockets 在闲置一分钟后就会断开连接。根据我在网上看到的东西,我都将责任归咎于代理或某些服务器设置或其他东西,但这不会发生在 IE 或 Edge 中。似乎如果套接字在一分钟不活动后被服务器断开连接,这将适用于 IE 和 Edge,就像 Chrome 和 Firefox 一样。
有人知道为什么吗?它记录在任何地方吗?我知道一种通过 ping 来阻止它的可能方法,但我对它发生的原因更感兴趣。 disconnect给出的原因码是1006,表示浏览器关闭了连接。不会抛出任何错误,也不会触发套接字的 onerror 事件。
该项目建立在 https://glitch.com/edit/#!/noiseless-helmet 上,您可以在其中查看和运行所有内容。客户端页面在此处提供: https ://noiseless-helmet.glitch.me/
这是我的客户页面:
<div id="div">
</div>
<script>
let socket = new WebSocket("wss://noiseless-helmet.glitch.me/");
socket.onmessage = function(event) {
div.innerHTML += "<br>message " + new Date().toLocaleString() + " " + event.data;
};
socket.onopen = function (event) {
div.innerHTML += "<br>opened " + new Date().toLocaleString();
socket.send("Hey socket! " + new Date().toLocaleString());
};
socket.onclose = function(event) {
div.innerHTML += "<br>socket closed " + new Date().toLocaleString();
div.innerHTML += "<br>code: " + event.code;
div.innerHTML += "<br>reason: " + event.reason;
div.innerHTML += "<br>clean: " + event.wasClean;
};
socket.onerror = function(event) {
div.innerHTML += "<br>error: " + event.error;
};
</script>
这是我的 Node.js 服务器代码:
var express = require('express');
var app = express();
app.use(express.static('public'));
let server = require('http').createServer(),
WebSocketServer = require('ws').Server,
wss = new WebSocketServer({ server: server });
app.get("/", function (request, response) {
response.sendFile(__dirname + '/views/index.html');
});
let webSockets = [];
wss.on('connection', function connection(socket) {
webSockets.push(socket);
webSockets.forEach((w) => { w.send("A new socket connected"); });
socket.on('close', (code, reason) => {
console.log('closing socket');
console.log(code);
console.log(reason);
let i = webSockets.indexOf(socket);
webSockets.splice(i, 1);
});
});
server.on('request', app);
server.listen(process.env.PORT, function () {
console.log('Your app is listening on port ' + server.address().port);
});
原文由 user12861 发布,翻译遵循 CC BY-SA 4.0 许可协议
嗯,不,它没有。 IE 和 Edge 可能 正在实施一个
ping
数据包作为 WebSocket 协议的一部分。WebSocket 协议包括对 JavaScript API 不公开的协议级别
ping
的支持。它比经常实施的用户级别 ping 级别低一些。这个
ping
-pong
流量会重置任何网络中介(代理、负载平衡器等)中的计时器 - 它们所有时间连接都标记为关闭的陈旧连接(例如, Heroku 设置连接时间为 55 秒)。大多数浏览器信任服务器来实现
ping
,这是礼貌的(因为服务器需要管理它们的负载和它们的 ping 超时………然而,这也有点令人沮丧,因为浏览器不知道连接是否异常丢失,并且 JavaScript 不会为 WebSocket 协议发出事件
ping
。这就是为什么许多 JavaScript 客户端实现用户级 ping(即 JSON{event: "ping", data: {...}}
或另一个“空”事件消息)的原因。不管怎样,我只是想指出你的假设是不正确的,这仍然是超时发生,浏览器行为的差异可能与浏览器本身有关。
有关 nginx 默认超时(代理 WebSocket 连接时)的一些细节,您可以阅读@Hendry 的回答。