第1部分:预期的行为?

我发现Firefox和Chrome之间的浏览器行为与被调用的onclose处理程序不一致。

如果Chrome是由用户页面导航/刷新引起的,则Chrome似乎不会触发onclose。但是,Firefox会触发onclose

在我看来,Firefox在这里的行为可能正确:



资料来源:http://www.w3.org/TR/2011/WD-websockets-20110419/#closeWebSocket

即使它可以导致一些sneaky code/unexpected behaviour

有人可以确认预期的行为吗?

第2部分:如何实现自动重新连接?

如果您有一个为用户自动重新连接的库,您如何知道是否应该尝试重新连接?您是否检查 CloseEvent.wasClean 属性?我必须假设“干净”意味着关闭应该通过对WebSocket.close()的API调用或服务器发送关闭帧来发生?如果网络错误导致关闭,我猜wasClean将是false吗?

在Pusher JavaScript库中,我们假设(onclose->等待->连接),除非我们处于关闭状态,否则关闭应该触发重新连接-开发人员选择关闭连接。似乎socket.io客户端库做出了相同的假设。

基于此,由用户导航/刷新引起的Firefox onclose事件会触发不必要的重新连接,因为这两个库都不检查CloseEvent.wasClean属性。

示例和视频

这是您可以用来证明不一致的示例:
http://jsbin.com/awonod/7

这是我演示问题的视频:
http://www.screenr.com/vHn8
(太晚了,请忽略一些滑动:))

需要注意的一点是,我按下Escape键也可能导致WebSocket连接关闭。但是,如果您仔细观察或自己尝试,则会在页面刷新之前看到close事件正在记录。

最佳答案

意外行为是由于Firefox和Chrome处理Websocket关闭的方式所致。刷新页面后,两个浏览器都会关闭连接,但是Firefox将执行您的onclose代码,而chrome将关闭连接并直接跳过以重新加载新页面。是的,我确认了这种奇怪的行为。
甚至更奇怪的是,据我观察,在chrome中调用websocket.close()会立即关闭连接并调用onclose函数,而Firefox等待从服务器返回的关闭消息。
如果从服务器收到关闭消息,则wasClean属性将为true
如果您的库在不检查wasClean属性的情况下自动重新连接,则可能会导致问题,因为它会在页面刷新时尝试重新建立连接。您应该考虑不使用该库并手动执行该操作,这应该不会很困难,只需使用if语句在onclose函数中调用connect即可确保onclean属性为true。为了更加安全,请在onbeforeunload中设置一个变量,以防止任何新连接。

希望这可以帮助!

07-26 05:57