【发布时间】:2012-06-13 12:13:00
【问题描述】:
第 1 部分:预期行为?
我发现 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
虽然可能会导致一些sneaky code/unexpected behaviour。
谁能确认预期的行为?
第二部分:如何实现自动重连?
如果您有一个为用户自动重新连接的库,您如何知道是否应该尝试重新连接?你检查CloseEvent.wasClean 属性吗?我不得不假设“干净”意味着关闭应该通过对WebSocket.close() 的 API 调用或服务器发送关闭帧来发生?如果网络错误导致关闭,我猜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 连接关闭。但是,如果您仔细观察或亲自尝试,您会看到在页面刷新之前记录了关闭事件。
【问题讨论】:
-
Pusher的链接和socket.io的链接一样。此外,# 行不再适用。应该链接到特定的提交,例如 github.com/socketio/socket.io-client/blob/…
标签: event-handling websocket reconnect