Java bayeux клиент отключается с TimeoutException при простое
Я инициализирую клиент 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 ms
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)
и несколько раз следующее:
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, но это только задерживает проблему. Почему Байе закрывает канал, а не проводит опрос? Я использую последнюю версию, org.cometd.java 4.0.2.
Также следует отметить тот факт, что у меня есть клиент Javascript, который работает без проблем.
Может кто-нибудь помочь?
1 ответ
Оказывается, я блокировал потоки cometD:
Я построил инструмент командной строки для проверки сервера, и когда я получил сообщение (с потоком из cometD), я держал этот поток для пользовательского ввода. Если я удерживаю этот поток достаточно долго, cometD отключается с вышеупомянутыми исключениями.
Решение: Когда вы получаете сообщение от CometD, не удерживайте его, используйте новую ветку.
Пульс по умолчанию контролируется на стороне сервера timeout
параметр, и это по умолчанию 30 секунд. Это означает, что длительный опрос, когда система бездействует, происходит каждые 30 секунд.
Вы настроили клиента idleTimeout
через 20 секунд, как видно из ваших следов стека исключений.
Когда система находится в режиме ожидания, клиент тайм-аут соединения, прежде чем ответ сердцебиение (длинный опрос), вызывая ошибки, которые вы видите.
Вам должно быть достаточно настроить клиент idleTimeout
до значения, превышающего сердцебиение timeout
или - что то же самое - установить сердцебиение timeout
на меньшее значение, чем клиент idleTimeout
,