正确关闭WebSocket(HTML5,Javascript)

And*_*Hin 118 javascript sockets html5 websocket

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

当用户只是在没有调用的情况下刷新页面时,会出现一种奇怪的行为websocket.close()- 当他们在刷新后返回时会触发该websocket.onclose事件.

kan*_*aka 98

根据协议规范 v76(这是具有当前支持工具的浏览器的版本):

要干净地关闭连接,从一个对等体发送一个由0xFF字节后跟一个0x00字节组成的帧,要求另一个对等体关闭连接.

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

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

window.onbeforeunload = function() {
    websocket.onclose = function () {}; // disable onclose handler first
    websocket.close();
};
Run Code Online (Sandbox Code Playgroud)

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

  • 使用`onbeforeunload`事件考虑[这些问题](http://stackoverflow.com/questions/14645011/window-onbeforeunload-and-window-onunload-is-not-working-in-firefox-safari-o) (4认同)
  • 在Firefox中,连接似乎可能会挂起到下一页加载中.我找不到参考,但我认为可能存在一个错误.另一种可能性是,当重新加载用户导航/页面时,"onclose"事件被意外触发,或者可能是故意触发.我[发布了一个问题](http://stackoverflow.com/questions/10965720/should-websocket-onclose-be-triggered-by-user-navigation-or-refresh)询问预期的行为应该是什么,哪个浏览器是否正确以及我们如何实现自动重新连接. (2认同)

kar*_*cow 36

很简单,你关闭它:)

var myWebSocket = new WebSocket("ws://example.org"); 
myWebSocket.send("Hello Web Sockets!"); 
myWebSocket.close();
Run Code Online (Sandbox Code Playgroud)

您是否还检查了以下网站并查看Opera介绍文章


小智 35

事实上,今天使用的WebSockets有2个主要协议版本.使用该[0x00][message][0xFF]协议的旧版本,然后是使用Hybi格式化数据包的新版本.

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

但是,对于使用新协议版本的浏览器(例如Firefox,Chrome和IE10),只有关闭浏览器才会导致浏览器自动关闭连接.也就是说,如果您刷新页面或离开页面,浏览器不会自动关闭连接.然而,浏览器做的是将hybi数据包发送到服务器,第一个字节(proto ident)正在0x88(更好地称为关闭数据帧).一旦服务器收到此数据包,它就可以强制关闭连接本身,如果您愿意的话.

  • 似乎很疯狂,它没有关闭连接.WebSocket变量在页面重新加载时被清除,那么如果无法访问连接,为什么连接会保持打开状态呢?重用连接也没有意义. (9认同)
  • 服务器端的一个实际例子如何管理这个hybi数据包? (4认同)

art*_*nig 5

正如theoobe提到的,某些浏览器不会自动关闭 websockets。不要尝试在客户端处理任何“关闭浏览器窗口”事件。如果您考虑支持主要桌面和移动浏览器(例如,onbeforeunload在 Mobile Safari 中不起作用),目前没有可靠的方法可以做到这一点。我在服务器端处理这个问题方面有很好的经验。例如,如果您使用 Java EE,请查看javax.websocket.Endpoint,具体取决于浏览器,如果您关闭/重新加载浏览器窗口,将调用该OnClose方法或该方法。OnError