第 1 部分:预期行为?
我看到 Firefox 和 Chrome 之间与onclose
被调用的处理程序有关的浏览器行为不一致。
onclose
如果它是由用户页面导航/刷新引起的,Chrome 似乎不会触发。但是,Firefox 确实会触发onclose
.
在我看来,Firefox 在这里的行为可能是正确的:
当 WebSocket 连接关闭时,可能是干净的,用户代理必须创建一个使用 CloseEvent 接口的事件,事件名称为 close,不冒泡,不可取消,没有默认操作,其 wasClean 属性设置为 true如果连接干净关闭,否则为false,其code属性设置为WebSocket连接关闭代码,其原因属性设置为WebSocket连接关闭原因;并排队一个任务,首先将 readyState 属性的值更改为 CLOSED (3),然后在 WebSocket 对象处分派事件。
资料来源:http ://www.w3.org/TR/2011/WD-websockets-20110419/#closeWebSocket
即使它可能导致一些鬼鬼祟祟的代码/意外行为。
任何人都可以确认预期的行为吗?
第 2 部分:如何实现自动重新连接?
如果您有一个为用户自动重新连接的库,您如何知道是否应该尝试重新连接?你检查CloseEvent.wasClean
财产吗?我不得不假设“干净”意味着关闭应该通过 API 调用WebSocket.close()
或服务器发送关闭帧来发生?如果网络错误导致关闭,我猜wasClean
会是false
什么?
在 Pusher JavaScript 库中,我们假设(onclose -> waiting -> connected)关闭应该触发重新连接,除非我们处于关闭状态 - 开发人员选择关闭连接。socket.io 客户端库似乎做出了相同的假设。
基于此,由用户导航/刷新引起的 Firefox onclose 事件会触发不需要的重新连接,因为两个库都不会检查该CloseEvent.wasClean
属性。
示例和视频
这是一个可用于演示不一致的示例:http: //jsbin.com/awonod/7
这是我演示问题的视频: http ://www.screenr.com/vHn8 (已经很晚了,忽略这两个错误:))
需要注意的一点是,我按下 Escape 键也可能导致 WebSocket 连接关闭。但是,如果您仔细观察或亲自尝试,您将看到在页面刷新之前记录的关闭事件。