0

在开发 Web 应用程序时,我遇到了一个似乎是 Jetty 的 WebSocket 连接管理的错误。我想知道是否有人不幸遇到了这个问题,如果是这样,他们是如何解决或避免这个问题的。

我遇到的问题分为三个部分:

  1. Jetty 无法识别客户端 WebSocket 已关闭(我没有收到 onClose 事件,并且 WebSocketConnection.isConnected() 返回 true)。请注意,我每秒 ping 一次客户端,但只有第一次 ping 失败:第一次 ping 之后的其他 ping 不返回结果(失败或成功)。

  2. 从客户端实际关闭时开始的所有消息都会累积起来,直到连接断开后 5 分钟才会失败,将所有未决消息转储到控制台并使用 java.nio.channels.InterruptedByTimeoutException

  3. 这些(失败的)未决消息不会被清除。所有发送到断开连接的客户端的消息,对于 Jetty 服务器曾经获得的每个 WebSocket 连接,每 5 分钟转储一次 InterruptedByTimeoutException。

在短期内,我的服务器仍然可以接受新的连接,我的应用程序仍然可以继续前进。但是,正如您可以想象的那样,一旦建立了足够多的这些消息,报告所有超时的线程就会占用执行时间,并且不会接受新的连接,HTTP、WebSocket 或其他方式。

我主要使用 Jetty 9.0.0.M2 对此进行了测试,但 9.0.0.M3 似乎也有同样的问题。对于那些感兴趣的人,这是我重现的具体步骤:

  1. 打开一个网页,该网页创建到您的 Jetty 9 服务器的 WebSocket 连接。(指出我的 WebSocket 是从 WebWorker 中打开的可能相关,也可能不相关)。
  2. 一旦 Jetty 从 Jetty 识别连接,开始每秒 ping 客户端并记录结果。
  3. 关闭您的客户端 WebSocket 页面正在运行的选项卡或浏览器。
  4. 仅观察一次 ping 失败。进一步的 ping 不会记录成功或失败。另请注意,您没有收到 onClose 事件。
  5. 等待 5 分钟,然后观察您的 Jetty 控制台爆炸,但对于每条从未完成的 ping 或消息,都会出现以下异常:

2013-01-12 19:39:52.747:WARN:oejwci.FrameBytes:Timer-3: org.eclipse.jetty.util.thread.TimerScheduler$SimpleTask.run(TimerScheduler) 失败(空)java.nio.channels.InterruptedByTimeoutException .java:88) 在 java.util.TimerThread.mainLoop(Unknown Source) 在 java.util.TimerThread.run(Unknown Source)

4

0 回答 0