【发布时间】:2024-01-21 06:30:01
【问题描述】:
我正在玩 HTML5 WebSockets。我想知道,如何优雅地关闭连接?比如,如果用户刷新页面,或者只是关闭浏览器会发生什么?
当用户只刷新页面而不调用 websocket.close() 时,会出现一种奇怪的行为 - 当他们在刷新后返回时,它会触发 websocket.onclose 事件。
【问题讨论】:
标签: javascript sockets html websocket
我正在玩 HTML5 WebSockets。我想知道,如何优雅地关闭连接?比如,如果用户刷新页面,或者只是关闭浏览器会发生什么?
当用户只刷新页面而不调用 websocket.close() 时,会出现一种奇怪的行为 - 当他们在刷新后返回时,它会触发 websocket.onclose 事件。
【问题讨论】:
标签: javascript sockets html websocket
很简单,你关闭它:)
var myWebSocket = new WebSocket("ws://example.org");
myWebSocket.send("Hello Web Sockets!");
myWebSocket.close();
您是否还检查了following site 并检查了introduction article of Opera
【讨论】:
根据protocol specv76(目前支持的浏览器实现的版本):
为了干净地关闭连接,一个帧只包含一个 0xFF 字节 后跟一个 0x00 字节从一个对等点发送以询问另一个对等点 关闭连接。
如果您正在编写服务器,则应确保在服务器关闭客户端连接时发送关闭帧。正常的 TCP 套接字关闭方法有时会很慢,并导致应用程序认为连接仍然打开,即使它不是。
当您关闭或重新加载页面时,浏览器确实应该为您执行此操作。但是,您可以通过捕获 beforeunload 事件来确保发送关闭帧:
window.onbeforeunload = function() {
websocket.onclose = function () {}; // disable onclose handler first
websocket.close();
};
我不确定在刷新页面后如何获得 onclose 事件。一旦页面重新加载,websocket 对象(带有 onclose 处理程序)将不再存在。如果您在页面加载时立即尝试在页面上建立 WebSocket 连接,那么您可能会遇到一个问题,即服务器在旧连接断开后不久就拒绝新连接(或者浏览器尚未准备好在您尝试连接的点建立连接)并且您将获得新 websocket 对象的 onclose 事件。
【讨论】:
onclose 事件被意外触发,或者可能是故意触发的,因为用户导航/页面重新加载。我已经posted a question 询问预期的行为应该是什么,哪个浏览器正确,以及我们如何实现自动重新连接。
onbeforeunload 事件
问题是目前使用的 WebSockets 有 2 个主要协议版本。旧版本使用[0x00][message][0xFF] 协议,新版本使用Hybi 格式数据包。
Opera 和 iPod/iPad/iPhone 使用旧协议版本,因此在 WebSockets 服务器中实现向后兼容性实际上很重要。在这些使用旧协议的浏览器中,我发现刷新页面、离开页面或关闭浏览器都会导致浏览器自动关闭连接。太好了!!
但是对于使用新协议版本的浏览器(例如 Firefox、Chrome 和最终的 IE10),仅关闭浏览器会导致浏览器自动关闭连接。也就是说,如果你刷新页面,或者离开页面,浏览器不会自动关闭连接。然而,浏览器所做的是向服务器发送一个 hybi 数据包,其中第一个字节(proto ident)是0x88(更好地称为关闭数据帧)。一旦服务器收到这个数据包,它可以强制关闭连接本身,如果你愿意的话。
【讨论】:
正如 theoobe 所述,某些浏览器不会自动关闭 websocket。不要尝试在客户端处理任何“关闭浏览器窗口”事件。如果您考虑支持主要的桌面 AND 移动浏览器(例如,onbeforeunload 在 Mobile Safari 中不起作用),目前没有可靠的方法来做到这一点。我在服务器端处理这个问题方面有很好的经验。例如。如果您使用 Java EE,请查看 javax.websocket.Endpoint,如果您关闭/重新加载浏览器窗口,将调用 OnClose 方法或 OnError 方法,具体取决于浏览器。
【讨论】:
通过使用web socket的close方法,你可以根据需要编写任何函数。
var connection = new WebSocket('ws://127.0.0.1:1337');
connection.onclose = () => {
console.log('Web Socket Connection Closed');
};
【讨论】:
请用这个
var uri = "ws://localhost:5000/ws";
var socket = new WebSocket(uri);
socket.onclose = function (e){
console.log(connection closed);
};
window.addEventListener("unload", function () {
if(socket.readyState == WebSocket.OPEN)
socket.close();
});
关闭浏览器不会触发 websocket 关闭事件。您必须手动调用 socket.close()。
【讨论】: