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