正确关闭 WebSocket (HTML5, Javascript)

2022-08-30 04:13:27

我正在玩HTML5 WebSockets。我想知道,我如何优雅地关闭连接?例如,如果用户刷新页面或只是关闭浏览器,会发生什么情况?

当用户只是刷新页面而不调用时,有一个奇怪的行为 - 当他们在刷新后返回时,它将命中事件。websocket.close()websocket.onclose


答案 1

根据协议规范 v76(这是当前支持此功能的浏览器实现的版本):

为了干净地关闭连接,从一个对等方发送一个仅由一个0xFF字节后跟一个0x00字节组成的帧,以请求另一个对等方关闭连接。

如果要编写服务器,则应确保在服务器关闭客户端连接时发送关闭帧。正常的 TCP 套接字关闭方法有时可能会很慢,并导致应用程序认为连接仍处于打开状态,即使它不是。

当您关闭或重新加载页面时,浏览器应该真正为您执行此操作。但是,您可以通过捕获unload之前的事件来确保发送关闭帧:

window.onbeforeunload = function() {
    websocket.onclose = function () {}; // disable onclose handler first
    websocket.close();
};

我不确定如何在刷新页面后获得关闭事件。一旦页面重新加载,websocket 对象(带有 onclose 处理程序)将不再存在。如果您在页面加载时立即尝试在页面上建立WebSocket连接,那么您可能会遇到这样一个问题:服务器在旧连接断开连接后不久就拒绝了新连接(或者浏览器在您尝试连接时尚未准备好建立连接),并且您正在为新的websocket对象获取onclose事件。


答案 2

它的事情是,目前使用的WebSockets有2个主要的协议版本。使用该协议的旧版本,然后是使用Hybi格式数据包的新版本[0x00][message][0xFF]

旧的协议版本由Opera和iPod / iPad / iPhone使用,因此在WebSockets服务器中实现向后兼容性实际上很重要。使用这些浏览器使用旧协议,我发现刷新页面,或导航离开页面,或关闭浏览器,都会导致浏览器自动关闭连接。伟大!!

但是,使用新协议版本的浏览器(例如。Firefox、Chrome和最终的IE10),只有关闭浏览器才会导致浏览器自动关闭连接。也就是说,如果您刷新页面或离开页面,浏览器不会自动关闭连接。但是,浏览器所做的是将hybi数据包发送到服务器,其中第一个字节(原型标识)是(更广为人知的关闭数据帧)。一旦服务器收到此数据包,它可以强制关闭连接本身,如果您愿意的话。0x88