为了账号安全,请及时绑定邮箱和手机立即绑定

Java bayeux 客户端在空闲时与 TimeoutException 断开连接

Java bayeux 客户端在空闲时与 TimeoutException 断开连接

达令说 2022-06-30 11:51:04
我正在初始化 Bayeux 客户端:SslContextFactory sslContextFactory = new SslContextFactory(true);HttpClient httpClient = new HttpClient(sslContextFactory);httpClient.start();Map<String, Object> options = new HashMap<String, Object>();ClientTransport transport = new LongPollingTransport(options, httpClient);BayeuxClient client =  new BayeuxClient("https://localhost:8483/cometd/", transport);client.handshake();boolean handshaken = client.waitFor(20000, BayeuxClient.State.CONNECTED);if (!handshaken) {    LOGGER.info("Failed to handshake");    throw new RuntimeException("Failed to handshake");}我用它与服务器进行一些通信,它可以工作,它订阅频道、发送、接收,然后我让它闲置一段时间。我得到以下异常:java.util.concurrent.TimeoutException: Idle timeout 20000 msat org.eclipse.jetty.client.http.HttpConnectionOverHTTP.onIdleExpired(HttpConnectionOverHTTP.java:145)at org.eclipse.jetty.io.ssl.SslConnection.onIdleExpired(SslConnection.java:286)at org.eclipse.jetty.io.AbstractEndPoint.onIdleExpired(AbstractEndPoint.java:401)at org.eclipse.jetty.io.IdleTimeout.checkIdleTimeout(IdleTimeout.java:166)at org.eclipse.jetty.io.IdleTimeout$1.run(IdleTimeout.java:50)at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)at java.util.concurrent.FutureTask.run(FutureTask.java:266)at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)at java.lang.Thread.run(Thread.java:748)
查看完整描述

2 回答

?
猛跑小猪

TA贡献1858条经验 获得超8个赞

事实证明,我阻塞了 cometD 线程:

我构建了一个命令行工具来检查服务器,当我收到一条消息(带有来自 cometD 的线程)时,我持有该线程以供用户输入。如果我持有该线程足够长的时间,cometD 将与上述异常断开连接。

解决方案:当你收到 CometD 的消息时,不要持有它,使用新线程。


查看完整回答
反对 回复 2022-06-30
?
子衿沉夜

TA贡献1828条经验 获得超3个赞

默认心跳由服务器端timeout参数控制,默认为30秒。这意味着当系统空闲时,长轮询每 30 秒发生一次。

您已idleTimeout在 20 秒时配置了客户端,这从您的异常堆栈跟踪中可以明显看出。

当系统空闲时,客户端将在心跳(长轮询)响应之前超时连接,导致您看到的错误。

将客户端配置为idleTimeout大于心跳的值就足够了timeout,或者 - 等效地 - 将心跳设置timeout为小于客户端的值idleTimeout


查看完整回答
反对 回复 2022-06-30
  • 2 回答
  • 0 关注
  • 136 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信