WebSocket.onclose应该由用户导航或刷新触发吗?

leg*_*ter 32 reconnect event-handling websocket

第1部分:预期的行为?

我发现Firefox和Chrome之间的浏览器行为与onclose被调用的处理程序有关.

onclose如果它是由用户页面导航/刷新引起的,Chrome似乎不会触发.但是,Firefox确实触发了onclose.

在我看来,Firefox可能在这里表现正常:

当WebSocket连接可能干净地关闭时,用户代理必须创建一个使用CloseEvent接口的事件,事件名称为close,不会冒泡,不可取消,没有默认操作,其wasClean属性设置为true如果连接干净,则为false,否则将其code属性设置为WebSocket连接关闭代码,并将其reason属性设置为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库中,我们假设(关闭 - >等待 - >连接)关闭应触发重新连接,除非我们处于关闭状态 - 开发人员已选择关闭连接.似乎socket.io客户端库做出了相同的假设.

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

示例和视频

这是一个可用于演示不一致性的示例:http: //jsbin.com/awonod/7

这是我演示问题的视频:http: //www.screenr.com/vHn8 (已经很晚了,忽略了几个漏洞:))

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

Opt*_*tox 5

出乎意料的行为是由于Firefox和Chrome处理Websocket关闭的方式.刷新页面时,两个浏览器都会关闭连接,但Firefox会执行您的onclose代码,而chrome会关闭连接并直接跳过重新加载新页面.所以是的,我证实了这种奇怪的行为.
更奇怪的是,根据我的观察,在chrome中调用websocket.close()将立即关闭连接并调用onclose函数,而Firefox则等待从服务器返回关闭消息.

如果从服务器收到关闭消息,则wasClean属性为true

如果您的库是自动重新连接而不检查wasClean属性,那么这可能会导致问题,因为它会在页面刷新时尝试重新建立连接.您应该考虑不使用该库并手动执行,它应该非常难,只需使用if语句调用onclose函数中的connect,确保onclean属性为true.或者更安全地在onbeforeunload中设置一个变量来阻止任何新连接.

希望这可以帮助!