一分钟不活动后 Chrome 和 Firefox 中的 WebSockets 断开连接 [英] WebSockets in Chrome and Firefox Disconnecting After One Minute of Inactivity

查看:90
本文介绍了一分钟不活动后 Chrome 和 Firefox 中的 WebSockets 断开连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

有谁知道这是为什么?它在任何地方都有记录吗?我知道一种通过 ping 来阻止它的可能方法,但我对它发生的原因更感兴趣.断开连接时给出的原因代码是 1006,表示浏览器关闭了连接.不会抛出任何错误并且不会触发套接字的 onerror 事件.

这个项目建立在 https://glitch.com/edit/#!/noiseless-helmet 在这里你可以看到和运行一切.客户端页面在此处提供:https://noiseless-helmet.glitch.me/

这是我的客户页面:

<脚本>let socket = new WebSocket("wss://noiseless-helmet.glitch.me/");socket.onmessage = 函数(事件){div.innerHTML += "<br>message " + new Date().toLocaleString() + " " + event.data;};socket.onopen = 函数(事件){div.innerHTML += "<br>opened " + new Date().toLocaleString();socket.send("嘿套接字!" + new Date().toLocaleString());};socket.onclose = 函数(事件){div.innerHTML += "<br>socket 关闭" + new Date().toLocaleString();div.innerHTML += "
代码:" + event.code;div.innerHTML += "<br>原因:" + event.reason;div.innerHTML += "<br>clean:" + event.wasClean;};socket.onerror = 函数(事件){div.innerHTML += "
错误:" + event.error;};

这是我的 Node.js 服务器代码:

var express = require('express');var app = express();app.use(express.static('public'));让 server = require('http').createServer(),WebSocketServer = require('ws').Server,wss = new WebSocketServer({ server: server });app.get("/", function (request, response) {response.sendFile(__dirname + '/views/index.html');});让 webSockets = [];wss.on('connection', 函数连接(socket) {webSockets.push(socket);webSockets.forEach((w) => { w.send("一个新的套接字已连接"); });socket.on('close', (code, reason) => {console.log('关闭套接字');控制台日志(代码);控制台日志(原因);让我 = webSockets.indexOf(socket);webSockets.splice(i, 1);});});server.on('request', app);server.listen(process.env.PORT,函数(){console.log('你的应用正在监听端口 ' + server.address().port);});

解决方案

如果套接字在不活动一分钟后被服务器断开连接,这将适用于 IE 和 Edge,就像 Chrome 和 Firefox 一样.

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

WebSocket 协议包括对协议级别的支持 ping JavaScript API 不公开.它比经常实现的用户级别 ping 级别低一些.

ping-pong 流量会重置任何网络中介(代理、负载均衡器等)中的计时器 - 它们始终连接以标记过时连接以供关闭(例如,Heroku 设置连接时间为 55 秒).

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

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

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

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

I have found that WebSockets in Chrome and Firefox disconnect after exactly one minute of inactivity. Based on stuff I've seen online, I was all set to blame proxies or some server settings or something, but this does not happen in IE or Edge. 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.

Does anyone know why this is? Is it documented anywhere? I know a possible way to stop it by pinging, but I'm more interested in why it's happening. The reason code given on disconnect is 1006, indicating that the browser closed the connection. No errors are thrown and the onerror event for the socket is not triggered.

This project was built at https://glitch.com/edit/#!/noiseless-helmet where you can see and run everything. The client page is served here: https://noiseless-helmet.glitch.me/

Here is my client page:

<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>

And here is my Node.js server code:

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.

Hmmm, no, it doesn't. IE and Edge might be implementing a ping packet as part of the WebSocket protocol.

The WebSocket protocol includes support for a protocol level ping that the JavaScript API doesn't expose. It's a bit lower-level than the user level pinging that is often implemented.

This ping-pong traffic resets the timers in any network intermediaries (proxies, load balancers, etc') - and they all time connections to mark stale connections for closure (for example, the Heroku setup times connections at 55 seconds).

Most browsers trust the server to implement the ping, which is polite (since servers need to manage their load and their timeout for pinging...

...however it's also slightly frustrating, since browsers have no idea if a connection was abnormally lost. This is why many JavaScript clients implement a user level ping (i.e., a JSON {event: "ping", data: {...}} or another "empty" event message).

Anyway, I just wanted to point out that your assumption was incorrect, this is still a timeout occurring and the difference in browser behavior is probably related to the browsers themselves.

For a few specifics regarding nginx default timeouts (when proxying WebSocket connections) you can read @Hendry's answer.

这篇关于一分钟不活动后 Chrome 和 Firefox 中的 WebSockets 断开连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆