一些Spring WebSocket会话永远不会断开连接

时间:2016-04-18 11:23:58

标签: java spring websocket spring-websocket

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

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

它们并不常见,但每天都会发生,60秒的时间似乎是合适的,因为它已硬编码到上面提到的Spring类中。但是在运行应用程序一段时间后,我开始获得大量这些真正长寿的超时':

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

此时应用程序开始遇到问题。

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

2 个答案:

答案 0 :(得分:2)

我们找到了一些东西:

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

    session.close(CloseStatus.SESSION_NOT_RELIABLE);

  4. 但我怀疑这并没有正确关闭会话。即使这样,移动客户端也会尝试重新连接。因此,当再过30秒时,另一个pong消息被发送到服务器,导致写入另一个这样的日志。等等......

    解决方案是编写一些服务器端代码以基于this project关闭旧的websockets,并修复移动客户端中的错误,即使处于屏幕保护模式时也会使ping / pong响应。< / p>

    哦,对其他人来说可能有用的一点是,客户永远不应该被信任,我们看到他们有时会在一毫秒内发送多个websockets请求,所以一定要处理这些重复请求&#39;某种方式!

答案 1 :(得分:0)

我也面临同样的问题。

Linux输出上的net stat显示tcp连接和状态如下:

  1 LISTEN
 13 ESTABLISHED
 67 CLOSE_WAIT

67个TCP连接正在等待关闭,但这些连接永远不会关闭。