use*_*861 11 javascript websocket node.js
我发现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>
Run Code Online (Sandbox Code Playgroud)
这是我的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);
});
Run Code Online (Sandbox Code Playgroud)
Hen*_*dry 10
据我从研究中了解到,这是由 websocket 在没有数据发送的一段时间内超时引起的。这可能是每个浏览器。
您可以使用 ping 来解决此问题,或者在需要再次使用套接字时重新连接。
当从服务器端和浏览器端不使用套接字时,不要保持套接字打开是有意义的。例如,Chrome 对可以打开的连接数有限制,如果限制是 64 个连接并且您打开了 64 个标签(这对我来说很可能,因为我总是打开大量标签)并且每个标签都连接到一个服务器,无法再连接(实际上类似的事情发生在我身上,当我用完 Chrome 中的可用套接字时,很有趣)。
有 proxy_read_timeout ( http://nginx.org/r/proxy_read_timeout ) 也适用于 WebSocket 连接。如果您的后端长时间不发送任何内容,则必须对其进行碰撞。或者,您可以将后端配置为定期发送 websocket ping 帧以重置超时(并检查连接是否仍然有效)。
https://forum.nginx.org/read.php?2,236382,236383#msg-236383
Web 套接字的空闲超时为 60 秒:如果您不通过 ping 和 pong 帧使用心跳或类似方法,则套接字假定用户已关闭页面并关闭套接字以节省资源。
https://www.codeproject.com/Questions/1205863/Websocket-is-closed-after-min
https://github.com/tornadoweb/tornado/issues/1070
闲置一分钟后,服务器似乎断开了套接字的连接,这与IE浏览器和Firefox一样适用于IE和Edge。
嗯,不,不是。IE和Edge 可能将ping数据包作为WebSocket协议的一部分来实现。
WebSocket协议包括ping对JavaScript API未公开的协议级别的支持。它比通常实现的用户级别ping低一些。
这ping- pong流量会重置任何网络中介(代理,负载平衡器等)中的计时器,并且它们所有的时间连接都会标记为过时的关闭连接(例如,Heroku设置时间为55秒)。
大多数浏览器都信任服务器来实施ping,这是礼貌的(因为服务器需要管理其负载和超时才能进行ping操作...
...但是,这也有点令人沮丧,因为浏览器不知道连接是否异常丢失。这就是为什么许多JavaScript客户端实现用户级ping(即JSON {event: "ping", data: {...}}或其他“空”事件消息)的原因。
无论如何,我只是想指出您的假设是不正确的,这仍然是超时,并且浏览器行为的差异可能与浏览器本身有关。
有关nginx默认超时(代理WebSocket连接时)的一些细节,您可以阅读@Hendry的答案。
| 归档时间: |
|
| 查看次数: |
7591 次 |
| 最近记录: |