java - 一些 Spring WebSocket session 永远不会断开连接

标签 java spring websocket spring-websocket

我有一个 websocket 解决方案,用于移动应用程序和 java 后端系统之间的双工通信。我正在使用 Spring WebSockets 和 STOMP。我已经实现了一个乒乓解决方案来保持 websockets 打开超过 30 秒,因为我需要比这更长的 session 。有时我会在日志中收到这些错误,这些错误似乎来自 checkSession() in Spring's SubProtocolWebSocketHandler .

server.log:07:38:41,090错误[org.springframework.web.socket.messaging.SubProtocolWebSocketHandler](ajp-http-executor-threads - 14526905)60205毫秒后没有收到消息。正在关闭 StandardWebSocketSession[id=214a10, uri=/base/api/websocket]。

它们不是很频繁,但每天都会发生,而且 60 秒的时间似乎很合适,因为它被硬编码到上面提到的 Spring 类中。但是,在运行应用程序一段时间后,我开始收到大量这些真正长期的“超时”:

server.log:00:09:25,961错误[org.springframework.web.socket.messaging.SubProtocolWebSocketHandler](ajp-http-executor-threads - 14199679)208049286毫秒后没有收到消息。正在关闭 StandardWebSocketSession[id=11a9d9, uri=/base/api/websocket]。

大约在这个时候,应用程序开始遇到问题。

我一直在尝试搜索此行为,但尚未在网络上的任何地方找到它。有没有人以前见过这个问题,知道解决方案,或者可以向我解释一下?

最佳答案

我们发现了一些东西:

  1. 我们在 STOMP 级别添加了自己的 ping/pong 功能,每 30 秒运行一次。
  2. 移动客户端存在一个错误,导致即使进入屏幕保护模式,它们仍会不断回复 ping。这意味着 websocket 永远不会关闭或超时。
  3. 在服务器收到的每条 pong 消息上,Spring 检查发现很长一段时间没有收到“真实”消息,并触发写入日志。然后它尝试使用以下代码关闭 websocket:

    session.close(CloseStatus.SESSION_NOT_RELIABLE);

但我怀疑这没有正确关闭 session 。即使确实如此,移动客户端也会尝试重新连接。因此,当又过了 30 秒时,另一条 pong 消息将发送到服务器,导致又一个日志被写入。永远如此......

解决方案是编写一些服务器端代码来关闭基于 this project 的旧 Websockets还修复了移动客户端中的错误,该错误使它们即使在屏幕保护模式下也能响应 ping/pong。

哦,对其他人来说可能有好处的一件事是,客户端永远不应该被信任,我们看到他们有时可以在一毫秒内发送多个 Websocket 请求,因此请确保处理这些“重复请求”方式!

关于java - 一些 Spring WebSocket session 永远不会断开连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36692582/

相关文章:

java - 在 Spring Boot 应用程序中调用 Apache CXF 客户端时无法创建安全的 XMLInputFactory

java - 如何将多个单选按钮分组到单选组下

javascript - Nginx add_header Sec-WebSocket-Protocol 不起作用

websocket - 如何使用 websocket-sharp 创建客户端?

java - 多个同步关键字如何在单个类中工作?

java - 线程中的异常 "main"org.hibernate.MappingException : Association references unmapped class hibernate

java - HTTP 响应无法获取响应正文

Spring MVC Autowired 组件中的 null

java - 使用 Spring 本地化异常消息

java - 本地主机上的 Apache Tomcat websockets 实现