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

Java bayeux客户端在空闲时与TimeoutException断开连接,java,comet,long-polling,cometd,bayeux,Java,Comet,Long Polling,Cometd,Bayeux,我正在初始化Bayeux客户端: SslContextFactory sslContextFactory = new SslContextFactory(true); HttpClient httpClient = new HttpClient(sslContextFactory); httpClient.start(); Map<String, Object> options = new HashMap<String, Object>(); ClientTranspo

我正在初始化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.nio.channels.ClosedChannelException: null
at org.eclipse.jetty.io.WriteFlusher.onClose(WriteFlusher.java:502)
at org.eclipse.jetty.io.AbstractEndPoint.onClose(AbstractEndPoint.java:353)
at org.eclipse.jetty.io.ChannelEndPoint.onClose(ChannelEndPoint.java:216)
at org.eclipse.jetty.io.AbstractEndPoint.doOnClose(AbstractEndPoint.java:225)
at org.eclipse.jetty.io.AbstractEndPoint.close(AbstractEndPoint.java:192)
at org.eclipse.jetty.io.AbstractEndPoint.close(AbstractEndPoint.java:175)
at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.doClose(SslConnection.java:1132)
at org.eclipse.jetty.io.AbstractEndPoint.doOnClose(AbstractEndPoint.java:220)
at org.eclipse.jetty.io.AbstractEndPoint.close(AbstractEndPoint.java:192)
at org.eclipse.jetty.io.AbstractEndPoint.close(AbstractEndPoint.java:175)
at org.eclipse.jetty.client.http.HttpConnectionOverHTTP.close(HttpConnectionOverHTTP.java:195)
at 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)
如果我让它忙,它不会失败。我尝试更改httpclient的超时,但这只会延迟问题。为什么Bayeux关闭频道而不是进行轮询?我使用的是最新版本org.cometd.java4.0.2

还需要注意的是,我有一个javascript客户端,可以毫无问题地工作


有人能帮忙吗?

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

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

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


将客户端
idleTimeout
配置为大于心跳
timeout
的值就足够了,或者-等效地-将heartbeat
timeout
设置为比客户端
idleTimeout
更小的值。默认的heartbeat在服务器端由
timeout
参数控制,默认值为30秒。 这意味着当系统空闲时,长轮询每30秒进行一次

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

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


您只需将客户端
idleTimeout
配置为大于心跳
timeout
的值,或者-等效地-将心跳
timeout
设置为小于客户端
idleTimeout

的值即可。结果表明,我阻塞了cometD线程:

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


解决方案:当您收到CometD的消息时,不要保留它,使用一个新线程。

结果是我阻止了CometD线程:

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


解决方案:当您收到CometD的消息时,不要保留它,使用新线程。

我将idleTimeout放大,如果放大,我将不再获得TimeoutException,但仍会获得ClosedChannel异常。在stackoverflow中很难进行故障排除。欢迎来到我们可以继续讨论的地方。一种猜测是,在客户端和正在关闭连接的Comet服务器之间还有其他东西,或者您没有在客户端和服务器中正确配置空闲超时。打开问题并附加调试日志。你试过了吗?我把IDletime放出来,如果我把它放大,我就不再得到TimeoutException,但我仍然得到ClosedChannel异常。在stackoverflow中很难进行故障排除。欢迎来到我们可以继续讨论的地方。一种猜测是,在客户端和正在关闭连接的Comet服务器之间还有其他东西,或者您没有在客户端和服务器中正确配置空闲超时。打开问题并附加调试日志。你试过了吗?有效吗?
java.nio.channels.ClosedChannelException: null
at org.eclipse.jetty.io.WriteFlusher.onClose(WriteFlusher.java:502)
at org.eclipse.jetty.io.AbstractEndPoint.onClose(AbstractEndPoint.java:353)
at org.eclipse.jetty.io.ChannelEndPoint.onClose(ChannelEndPoint.java:216)
at org.eclipse.jetty.io.AbstractEndPoint.doOnClose(AbstractEndPoint.java:225)
at org.eclipse.jetty.io.AbstractEndPoint.close(AbstractEndPoint.java:192)
at org.eclipse.jetty.io.AbstractEndPoint.close(AbstractEndPoint.java:175)
at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.doClose(SslConnection.java:1132)
at org.eclipse.jetty.io.AbstractEndPoint.doOnClose(AbstractEndPoint.java:220)
at org.eclipse.jetty.io.AbstractEndPoint.close(AbstractEndPoint.java:192)
at org.eclipse.jetty.io.AbstractEndPoint.close(AbstractEndPoint.java:175)
at org.eclipse.jetty.client.http.HttpConnectionOverHTTP.close(HttpConnectionOverHTTP.java:195)
at 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)