我正在玩HTML5 WebSockets。我想知道,如何优雅地关闭连接?比如,如果用户刷新页面或只是关闭浏览器会发生什么?
当用户只是在不调用websocket.close()
的情况下刷新页面时会有一种奇怪的行为 - 当他们在刷新后返回时会触及websocket.onclose
事件。
根据protocol spec v76(这是具有当前支持工具的浏览器的版本):
要干净地关闭连接,从一个对等体发送一个由0xFF字节后跟一个0x00字节组成的帧,要求另一个对等体关闭连接。
如果您正在编写服务器,则应确保在服务器关闭客户端连接时发送关闭帧。正常的TCP套接字关闭方法有时可能很慢并且导致应用程序认为连接仍然是打开的,即使它不是。
当您关闭或重新加载页面时,浏览器应该真的为您执行此操作。但是,您可以通过捕获beforeunload事件来确保发送关闭帧:
window.onbeforeunload = function() {
websocket.onclose = function () {}; // disable onclose handler first
websocket.close();
};
我不确定如何在页面刷新后获得onclose事件。一旦页面重新加载,websocket对象(带有onclose处理程序)将不再存在。如果您在页面加载时立即尝试在页面上建立WebSocket连接,那么您可能会遇到服务器在旧连接断开后很快拒绝新连接的问题(或浏览器未准备就绪)在您尝试连接的位置建立连接)并且您正在为新的websocket对象获取一个onclose事件。
很简单,你关闭它:)
var myWebSocket = new WebSocket("ws://example.org");
myWebSocket.send("Hello Web Sockets!");
myWebSocket.close();
事实上,今天使用的WebSockets有2个主要协议版本。使用[0x00][message][0xFF]
协议的旧版本,然后是使用Hybi格式化数据包的新版本。
旧的协议版本由Opera和iPod / iPad / iPhone使用,因此在WebSockets服务器中实现向后兼容性非常重要。使用旧协议的这些浏览器,我发现刷新页面,导航离开页面或关闭浏览器都会导致浏览器自动关闭连接。大!!
但是,对于使用新协议版本的浏览器(例如Firefox,Chrome和IE10),只有关闭浏览器才会导致浏览器自动关闭连接。也就是说,如果您刷新页面或离开页面,浏览器不会自动关闭连接。然而,浏览器的作用是将一个hybi数据包发送到服务器,第一个字节(proto ident)是0x88
(更好地称为关闭数据帧)。一旦服务器收到此数据包,它就可以强制关闭连接本身,如果您愿意的话。
正如theoobe所提到的,某些浏览器不会自动关闭websockets。不要尝试处理客户端的任何“关闭浏览器窗口”事件。如果你考虑支持主要的桌面和移动浏览器(例如onbeforeunload
在Mobile Safari中不起作用),目前还没有可行的方法。我在处理服务器端这个问题方面有很好的经验。例如。如果使用Java EE,请查看javax.websocket.Endpoint,根据浏览器的不同,如果关闭/重新加载浏览器窗口,将调用OnClose
方法或OnError
方法。
通过使用Web套接字的close方法,您可以根据需要编写任何函数。
var connection = new WebSocket('ws://127.0.0.1:1337');
connection.onclose = () => {
console.log('Web Socket Connection Closed');
};