假设我们在客户端和 javaee 服务器之间打开了 websocket。有一个方法 session.isOpen() 可以用来检查会话是否仍然打开。但是什么会返回这个方法以及为什么如果客户端计算机突然关闭或用户离开页面但我们的 js 脚本没有关闭连接。这种方法的可靠性如何?
2 回答
简短的回答
当用户离开页面时,浏览器应该关闭任何 WebSockets 连接。因此,该Session#isOpen()
方法应该返回false
。
Session#setMaxIdleTimeout(long)
如果会话处于非活动状态(没有发送或接收消息),您始终可以使用该方法设置容器关闭会话之前的毫秒数。当浏览器未按预期关闭连接时,它很有用。
长答案
当前的 HTML Live 标准定义了以下有关卸载文档的内容:
本规范定义了以下卸载文档清理步骤。其他规范可以定义更多。
使构造函数
WebSocket
创建的任何对象从's对象中消失。如果这影响了任何对象,则将's salvageable state 设置为 false。WebSocket()
Document
Window
WebSocket
Document
如果
Document
' 的可挽救状态为 false,则强制关闭从'对象EventSource
调用其构造函数的任何对象。Document
Window
如果
Document
' 的可挽救状态为假,则清空Document
'Window
的活动计时器列表。
关于制作消失WebSocket
对象,定义如下:
如果用户代理要使
WebSocket
对象消失(当Document
对象消失时会发生这种情况),则用户代理必须遵循以下列表中的第一组适当步骤:
如果尚未建立 WebSocket 连接
- WebSocket 连接失败。
如果 WebSocket 关闭握手尚未开始
- 启动 WebSocket 关闭握手,在 WebSocket Close 消息中使用的状态码是
1001
.否则
- 没做什么。
换句话说,浏览器应该在您离开页面时关闭 WebSockets 连接。
RFC 6455定义了这种情况的1001
状态码:
端点在发送关闭帧时可以使用以下预定义的状态代码。
1000
1000
表示正常关闭,意味着建立连接的目的已经实现。
1001
1001
表示端点正在“消失”,例如服务器关闭或浏览器已导航离开页面。[...]
您将在下面找到有关 Chrome 和 Firefox 中报告的问题的更多详细信息:
javax.websocket.Session#isOpen()
如果 WebSocket 连接处于活动状态 - 即能够创建javax.websocket.Session
. 如果您javax.websocket.Session#close()
在特定会话上调用Session
,然后javax.websocket.Session#isOpen()
在同一个会话上调用,它将始终返回 true,因为底层 WebSocket 仍将处于活动状态并能够创建新的Session
. 模棱两可,不是吗?
但是,在您javax.websocket.Session#close()
再打电话之后,session.getOpenSessions().size()
您会看到计数会减少。
简而言之 - 如果 WebSocket 连接处于活动状态,则#isOpen()
始终返回 true。