Answers:
根据协议规范 v76(具有当前支持的浏览器实现的版本):
为了干净地关闭连接,从一个对等方发送一个仅包含0xFF字节后跟0x00字节的帧,以要求另一对等方关闭连接。
如果要编写服务器,则应确保在服务器关闭客户端连接时发送关闭帧。常规的TCP套接字关闭方法有时可能会很慢,并且导致应用程序认为该连接仍处于打开状态,即使没有打开也是如此。
当您关闭或重新加载页面时,浏览器确实应该为您执行此操作。但是,可以通过捕获beforeunload事件来确保发送关闭帧:
window.onbeforeunload = function() {
websocket.onclose = function () {}; // disable onclose handler first
websocket.close();
};
我不确定页面刷新后如何获得onclose事件。页面重新加载后,websocket对象(带有onclose处理函数)将不再存在。如果您在页面加载时立即尝试在页面上建立WebSocket连接,那么您可能会遇到这样的问题:服务器在旧连接断开后不久(新的浏览器未准备好)拒绝了新的连接以在您尝试连接的位置进行连接),并且您将获得新websocket对象的onclose事件。
事实是,当今有2个主要的WebSocket协议版本正在使用。使用[0x00][message][0xFF]
协议的旧版本,然后使用Hybi格式的数据包的新版本。
Opera和iPod / iPad / iPhone使用旧的协议版本,因此在WebSockets服务器中实现向后兼容性实际上很重要。在使用旧协议的这些浏览器中,我发现刷新页面,离开页面导航或关闭浏览器,所有这些都会导致浏览器自动关闭连接。大!!
但是,对于使用新协议版本的浏览器(例如Firefox,Chrome和最终的IE10),仅关闭浏览器将导致浏览器自动关闭连接。也就是说,如果刷新页面或浏览离开页面,浏览器不会自动关闭连接。但是,浏览器的作用是向服务器发送一个hybi数据包,其第一个字节(原型身份)为0x88
(最好称为关闭数据帧)。服务器收到此数据包后,可以选择自行关闭连接。
如theoobe所述,某些浏览器不会自动关闭websocket。不要尝试在客户端处理任何“关闭浏览器窗口”事件。如果您考虑支持主要的台式机和移动浏览器(例如,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');
};
onclose
,当用户导航/页面重新加载时,事件被意外触发,或者有意触发。我已经发布了一个问题,询问预期的行为是什么,哪种浏览器正确,以及我们如何实现自动重新连接。