Understanding the keepalive loop ("/meta/connect")

459 views
Skip to first unread message

Cosimo

unread,
Mar 1, 2019, 10:34:00 AM3/1/19
to cometd-users
Hi,

I'm trying to figure out the exact details of how the keepalive loop
is working in the bayeux protocol.

We have a legacy server application using Cometd 2.x (which
we can't upgrade without major issues) that is showing some
strange behaviour, or maybe the javascript clients are?

We use websockets as preferred transport. This is what I observe:

→ [ 46] /meta/connect  "advice":{"timeout":0},"connectionType":"websocket","id":4
← [ 89] /meta/connect  "advice":{"interval":0,"reconnect":"retry","timeout":30000},"id":4,"successful":true
→ [ 91] /meta/connect  "connectionType":"websocket","id":6
← [ 97] /meta/connect  "advice":{"interval":0,"reconnect":"retry","timeout":30000},"id":5,"successful":true

Where the second number is the milliseconds since the start of the
communication exchange between client and server.

What I don't understand is the criterion used from the server to decide *when* to
send the /meta/connect replies. I looked at the cometd source code here:


and followed the publish3 -> publish2 -> publish chain upwards, but haven't
understood what is delaying the reply or where that delay logic is implemented.

If I mock a bayeux server, connect a faye js cometd client to it and do not delay
the connect replies from the server, the client will happily flood the channel
with connect requests as fast as it can, regardless of what value of "interval" I set,
which seems to contradict what I can read here:


Would appreciate if you could enlighten me.
Cheers,

--
Cosimo

Simone Bordet

unread,
Mar 1, 2019, 10:58:01 AM3/1/19
to cometd-users
Hi,

On Fri, Mar 1, 2019 at 4:34 PM Cosimo <cosi...@streppone.it> wrote:
>
> Hi,
>
> I'm trying to figure out the exact details of how the keepalive loop
> is working in the bayeux protocol.
>
> We have a legacy server application using Cometd 2.x (which
> we can't upgrade without major issues)

FYI, migrations guides are available:
https://docs.cometd.org/current/reference/#_migration

> that is showing some
> strange behaviour, or maybe the javascript clients are?

You have custom JavaScript clients or the same version CometD JavaScript client?

> We use websockets as preferred transport. This is what I observe:
>
> → [ 46] /meta/connect "advice":{"timeout":0},"connectionType":"websocket","id":4
> ← [ 89] /meta/connect "advice":{"interval":0,"reconnect":"retry","timeout":30000},"id":4,"successful":true
> → [ 91] /meta/connect "connectionType":"websocket","id":6
> ← [ 97] /meta/connect "advice":{"interval":0,"reconnect":"retry","timeout":30000},"id":5,"successful":true
>
> Where the second number is the milliseconds since the start of the
> communication exchange between client and server.
>
> What I don't understand is the criterion used from the server to decide *when* to
> send the /meta/connect replies. I looked at the cometd source code here:
>
> https://github.com/cometd/cometd/blob/4.0.x/cometd-java/cometd-java-server/src/main/java/org/cometd/server/BayeuxServerImpl.java#L1385

Well, you should look at the CometD 2.x code, not 4.x :)

The logic is as follows: the client can send a hint to the server
(advice: { timeout: 0}) to ask the server to *not* hold the heartbeat.
Your log above shows an immediate (well, 45 ms later) response as expected.

If the client does not send any hint, the server decides when to
return the heartbeat.
Your logs above show again an immediate response.
To explain I would need the exact server configuration.
The immediate response can be explained by the server being configured
with the ack extension and with a message ready to be delivered to the
client: as soon as the client heartbeat arrives to the server, the
server sees it has a message to deliver, sees the ack extension and
returns the heartbeat immediately.

> If I mock a bayeux server, connect a faye js cometd client to it and do not delay
> the connect replies from the server, the client will happily flood the channel
> with connect requests as fast as it can, regardless of what value of "interval" I set,
> which seems to contradict what I can read here:
>
> https://docs.cometd.org/current4/reference/#_bayeux_meta_connect

I think you misunderstood what you read.

"interval" is the delay that the *client* needs to wait for, from the
moment it receives a heartbeat reply to the moment it sends the next
heartbeat message.
"timeout" is the delay that the *server* needs to wait if there is no
reason to reply to the heartbeat sooner.

If you mock a server without respecting the "timeout" semantic and the
client advice, then yes the client will go in a tight loop sending
heartbeats.

I would not recommend to use a Faye client - while it may work as both
Faye and CometD use the Bayeux protocol, there have been in the past
different interpretations of the mechanic of the protocol and I'm not
sure Faye supports the CometD extensions with the same semantic.

--
Simone Bordet
----
http://cometd.org
http://webtide.com
Developer advice, training, services and support
from the Jetty & CometD experts.

Cosimo

unread,
Mar 1, 2019, 12:06:20 PM3/1/19
to cometd...@googlegroups.com
Hi Simone,

On Fri, Mar 1, 2019, at 16:58, Simone Bordet wrote:

> You have custom JavaScript clients or the same version CometD JavaScript client?

We use(d) Faye, currently version 1.2.4.

> > What I don't understand is the criterion used from the server to decide *when* to
> > send the /meta/connect replies.
>
> The logic is as follows: the client can send a hint to the server
> (advice: { timeout: 0}) to ask the server to *not* hold the heartbeat.
>
> If the client does not send any hint, the server decides when to
> return the heartbeat.

Ok, so if client sends no `advice` then the server decides, and at most
the wait will be 30s by default. At least that's what I see.

> The immediate response can be explained by the server being configured
> with the ack extension and with a message ready to be delivered to the
> client: as soon as the client heartbeat arrives to the server, the
> server sees it has a message to deliver, sees the ack extension and
> returns the heartbeat immediately.

I'm not exactly sure what you mean by server configuration.
As far as I know, there is no specific cometd server configuration.
Both the client and server use the Ack and Timesync extensions.

> "timeout" is the delay that the *server* needs to wait if there is no
> reason to reply to the heartbeat sooner.
>
> If you mock a server without respecting the "timeout" semantic and the
> client advice, then yes the client will go in a tight loop sending
> heartbeats.

I understand then that `timeout` is the *max* delay the server is
waiting before sending a connect reply, even in the presence of
the Ack extension. BTW, it's not clear to me why with the Ack
extension the server would need to always reply right away, but
probably not important.

> I would not recommend to use a Faye client - while it may work as both
> Faye and CometD use the Bayeux protocol, there have been in the past
> different interpretations of the mechanic of the protocol and I'm not
> sure Faye supports the CometD extensions with the same semantic.

Ok, that's good to know. I'll explore that path as well.
Thanks for the above information.

Are you aware of any Python cometd server implementations?

--
Cosimo

Simone Bordet

unread,
Mar 1, 2019, 12:13:55 PM3/1/19
to cometd-users
Hi,

On Fri, Mar 1, 2019 at 6:06 PM Cosimo <cosi...@streppone.it> wrote:
>
> Hi Simone,
>
> On Fri, Mar 1, 2019, at 16:58, Simone Bordet wrote:
>
> > You have custom JavaScript clients or the same version CometD JavaScript client?
>
> We use(d) Faye, currently version 1.2.4.

As I said, not recommended. Can you ask you why you use Faye instead
of the CometD client?

> > The immediate response can be explained by the server being configured
> > with the ack extension and with a message ready to be delivered to the
> > client: as soon as the client heartbeat arrives to the server, the
> > server sees it has a message to deliver, sees the ack extension and
> > returns the heartbeat immediately.
>
> I'm not exactly sure what you mean by server configuration.
> As far as I know, there is no specific cometd server configuration.
> Both the client and server use the Ack and Timesync extensions.

So the server is configured with the Ack and Timesync extension :)

> I understand then that `timeout` is the *max* delay the server is
> waiting before sending a connect reply, even in the presence of
> the Ack extension. BTW, it's not clear to me why with the Ack
> extension the server would need to always reply right away, but
> probably not important.

It's to guarantee ordered delivery when using the HTTP transport and
while WebSocket would not need that, we keep the same semantic.

> Are you aware of any Python cometd server implementations?

Not that I know.
There are a Java and NodeJS server implementation that the CometD
project maintains.
Reply all
Reply to author
Forward
0 new messages