2

I'm initializing Bayeux client:

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");
}

I use it for some communication with server, it works, it subscribes to channels, sends, receives, then I leave it idle for a while. I get the following exceptions:

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)

and multiple times the following:

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)

If I keep it busy it doesn't fail. I tried changing the timeout of the httpclient, but that only delays the problem. Why does Bayeux close the channel instead of doing polling? I use the latest version, org.cometd.java 4.0.2.

Also to be noticed is the fact that I have a javascript client that works with no problems.

Can somebody help?

Tudor
  • 2,224
  • 2
  • 21
  • 24

2 Answers2

1

It turns out that I was blocking the cometD threads:

I built a commandline tool to inspect the server, and when I received a message (with a thread from cometD), I was holding that thread for user Input. If I hold that thread long enough cometD disconnects with the aforementioned exceptions.

Solution: When you receive a message from CometD, don't hold it, use a new thread.

Tudor
  • 2,224
  • 2
  • 21
  • 24
0

The default heartbeat is controlled on the server-side by the timeout parameter, and it's by default 30 seconds. This means that the long poll, when the system is idle, happens every 30 second.

You have configured the client idleTimeout at 20 second, as it is evident from your exception stack traces.

When the system is idle, the client will timeout the connection before the heartbeat (the long poll) is responded, causing the errors you see.

It should be enough for you to configure the client idleTimeout to a value larger than the heartbeat timeout, or - equivalently - set the heartbeat timeout to a smaller value than the client idleTimeout.

sbordet
  • 16,856
  • 1
  • 50
  • 45
  • I put whatever idleTimeout, if I put it larger I no longer get the TimeoutException, but I still get the ClosedChannelException. – Tudor Mar 08 '19 at 08:50
  • It is difficult to troubleshoot here in stackoverflow. You are welcome to [open an issue at the CometD project](https://github.com/cometd/cometd/issues) where we can continue the discussion. A wild guess is that you have something else in between the client and the CometD server that is closing the connection, or you have not configured the idle timeout properly in both the client and the server. Open an issue and attach DEBUG logs. Have you tried to [deploy the CometD demo](https://docs.cometd.org/current/reference/#_installation_demos) and does it work? – sbordet Mar 08 '19 at 15:38