假设我们在客户端和javaee服务器之间打开了websocket。有一个方法session.isOpen(),可用于检查会话是否仍处于打开状态。但是什么将返回此方法以及为什么如果客户端计算机突然关闭或用户离开页面但我们的js脚本没有关闭连接。这种方法有多可靠?
当用户离开页面时,浏览器应该关闭任何WebSockets连接。因此,Session#isOpen()
方法应返回false
。
您始终可以使用Session#setMaxIdleTimeout(long)
方法设置容器关闭会话之前的毫秒数(如果它处于非活动状态(未发送或接收任何消息))。当浏览器未按预期关闭连接时,它很有用。
当前的HTML Live Standard定义了以下关于unloading documents的内容:
该规范定义了以下卸载文档清理步骤。其他规格可以定义更多。
- 使
WebSocket
构造函数从WebSocket()
的Document
对象创建的任何Window
对象消失。如果这会影响任何WebSocket
对象,则将Document
的可恢复状态设置为false。- 如果
Document
的可挽救状态是假的,强行关闭任何EventSource
对象,其构造函数是从Document
的Window
对象调用的。- 如果
Document
的可挽救状态为假,则清空Document
的Window
的活动计时器列表。
关于making disappear WebSocket
objects,定义如下:
如果要使用户代理消失
WebSocket
对象(这在Document
对象消失时发生),则用户代理必须遵循以下列表中的第一组适当步骤:
- 如果尚未建立WebSocket连接 WebSocket连接失败。
- 如果尚未启动WebSocket关闭握手 启动WebSocket关闭握手,在WebSocket关闭消息中使用的状态代码为
1001
。- 除此以外 没做什么。
换句话说,当您离开页面时,浏览器应该关闭WebSockets连接。
RFC 6455为这种情况定义了1001
状态代码:
发送关闭帧时,端点可以使用以下预定义的状态代码。
1000
1000
表示正常关闭,这意味着已建立连接的目的已经实现。1001
1001
表示端点正在“离开”,例如服务器关闭或浏览器已离开页面。[...]
您可以在下方找到有关Chrome和Firefox中报告的问题的更多详细信息:
如果WebSocket连接处于活动状态,javax.websocket.Session#isOpen()
将返回true - 即能够创建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。