javascript - Chrome 和 Firefox 中的 WebSocket 在一分钟不活动后断开连接

标签 javascript node.js websocket

我发现 Chrome 和 Firefox 中的 WebSockets 会在完全不活动一分钟后断开连接。根据我在网上看到的东西,我都准备归咎于代理或某些服务器设置或其他东西,但这在 IE 或 Edge 中不会发生。看起来如果套接字在一分钟不活动后被服务器断开,这将适用于 IE 和 Edge,就像 Chrome 和 Firefox 一样。

有人知道这是为什么吗?它在任何地方都有记录吗?我知道通过 ping 来阻止它的可能方法,但我对它发生的原因更感兴趣。断开连接时给出的原因码是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);
});

最佳答案

It seems like if sockets are disconnected by the server after one minute of inactivity that would apply to IE and Edge just as much as Chrome and Firefox.

嗯,不,它没有。 IE 和 Edge 可能ping 数据包实现为 WebSocket 协议(protocol)的一部分。

The WebSocket protocol includes support for a protocol level ping JavaScript API 没有公开。它比通常实现的用户级 ping 的级别要低一些。

ping-pong 流量会重置任何网络中介(代理、负载平衡器等)中的计时器 - 它们都会对连接进行计时以标记陈旧的连接以供关闭(例如,Heroku setup times connections at 55 seconds)。

大多数浏览器信任服务器来实现 ping,这是礼貌的(因为服务器需要管理它们的负载和它们的 ping 超时......

...不过也有点令人沮丧,因为浏览器不知道连接是否异常丢失,并且 JavaScript 不会为 WebSocket 协议(protocol) ping 发出事件。这就是为什么许多 JavaScript 客户端实现用户级 ping(即 JSON {event: "ping", data: {...}} 或另一个“空”事件消息)的原因。

无论如何,我只是想指出您的假设是不正确的,这仍然是超时发生并且浏览器行为的差异可能与浏览器本身有关。

有关 nginx 默认超时(代理 WebSocket 连接时)的一些细节,您可以阅读@Hendry 的答案。

关于javascript - Chrome 和 Firefox 中的 WebSocket 在一分钟不活动后断开连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49408031/

相关文章:

javascript - 使用 jQuery 更改具有默认值的链接类

javascript - 更新 Rails 站点中的 Jcrop 图像

javascript - chrome 扩展中的 Puppeteer,没有 puppeteer-web

node.js - 使用 .where() Query with .update() 通过 Mongoose ?

javascript - 套接字io事件触发多次

python - Python Tornado中的已连接客户端列表

javascript - 如何使用 Three.js 沿弧线打印文本?

php - 向 php 脚本提交同名表单?

javascript - 服务器使用 node.js (express) 发送事件/事件源

proxy - WebSockets 和应用程序代理连接问题