WebSocket.onclose 应该由用户导航触发还是刷新触发? [英] Should WebSocket.onclose be triggered by user navigation or refresh?

查看:45
本文介绍了WebSocket.onclose 应该由用户导航触发还是刷新触发?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现 Firefox 和 Chrome 之间在调用 onclose 处理程序方面存在一些不一致的浏览器行为.

I'm seeing some inconsistent browser behaviour between Firefox and Chrome in relation to the onclose handler being called.

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

It seems that Chrome does not trigger an onclose if it was caused by a user page navigation/refresh. However, Firefox does trigger the onclose.

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

It seems to me that Firefox may be behaving correctly here:

当 WebSocket 连接关闭时,可能是干净的,用户代理必须创建一个使用 CloseEvent 接口的事件,事件名称为 close,不冒泡,不可取消,没有默认操作,其 wasClean 属性为如果连接干净关闭则设置为true,否则设置为false,其代码属性设置为WebSocket连接关闭代码,其原因属性设置为WebSocket连接关闭原因;并排队一个任务,首先将 readyState 属性的值更改为 CLOSED (3),然后在 WebSocket 对象上调度事件.

When the WebSocket connection is closed, possibly cleanly, the user agent must create an event that uses the CloseEvent interface, with the event name close, which does not bubble, is not cancelable, has no default action, whose wasClean attribute is set to true if the connection closed cleanly and false otherwise, whose code attribute is set to the WebSocket connection close code, and whose reason attribute is set to the WebSocket connection close reason; and queue a task to first change the readyState attribute's value to CLOSED (3), and then dispatch the event at the WebSocket object.

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

即使它可能导致一些偷偷摸摸的代码/意外行为.

谁能确认预期的行为?

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

If you have a library that auto-reconnects for the user how do you know if you should try to reconnect? Do you check the CloseEvent.wasClean property? I'm having to assume that 'clean' means that the close was supposed to happen through either an API call to WebSocket.close() or the server sending a close frame? If a network error causes the close I'm guessing the wasClean would be false?

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

In the Pusher JavaScript library we assumed (onclose -> waiting -> connecting) that a close should trigger a reconnect unless we are in a closing state - the developer has chosen to close the connection. It would appear that the socket.io client library makes the same assumption.

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

Based on this the Firefox onclose event caused by user navigation/refresh triggers an unwanted reconnection because neither library check the CloseEvent.wasClean property.

下面是一个示例,您可以使用它来演示不一致:http://jsbin.com/awonod/7

Here's an example that you can use to demonstrate the inconsistency: http://jsbin.com/awonod/7

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

Here's a video of me demonstrating the problem: http://www.screenr.com/vHn8 (it's late, ignore the couple of slip-ups :))

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

One point to note is that my hitting the Escape key could also be causing the WebSocket connection to close. However, if you watch closely or try for yourself you will see the close event being logged just before the page refreshes.

推荐答案

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

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

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

The unexpected behavior is due to the way in which Firefox and Chrome handle the closing of a Websocket. When the page is refreshed, both browsers close the connection, however, Firefox will execute your onclose code, while chrome closes the connection and skips straight to re-loading the new page. So yes, I confirm this strange behavior.
Even stranger is the fact that, from my observations, calling websocket.close() in chrome will immediately close the connection and call the onclose function, while Firefox waits for a close message back from the server.

The wasClean property will be true if a close message was received from the server

If your library is auto-reconnecting without checking the wasClean property then this could cause a problem, as it tries to re-establish the connection as the page refreshes. You should consider not using the library for this and doing it manually, it should'nt be very hard, just call connect in the onclose function with an if statement making sure the onclean property is true. Or to be even more safe set a variable in onbeforeunload that prevents any new connection.

希望这会有所帮助!

这篇关于WebSocket.onclose 应该由用户导航触发还是刷新触发?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆