Skip navigation.

Why the CometD server sends messages twice ?

Why the CometD server sends messages twice ?

You have a JavaScript CometD client that subscribed to a channel and while publishing to that channel, you notice that it receives the message twice.

This is very common when you have written a Bayeux service like this:

public class MyService extends BayeuxService
    public MyService(Bayeux bayeux)
        super(bayeux, "my-service");
        subscribe("/my/channel", "processMyMessage");

    public void processMyMessage(Client remote, Message message)
        getBayeux().getChannel(message.getChannel(), false).publish(getClient(), message.getData(), null);

Let's put ourselves in the CometD Server's shoes for a moment: it sees 2 clients subscribed to channel "/my/channel": a remote client that subscribed via the JavaScript API, and a server-side client that is associated to the Bayeux service MyService and that in our example subscribed in MyService's constructor via the subscribe() call.

When the CometD server receives a message on channel "/my/channel" and notifies the clients, the remote client gets the first message, and MyService.processMyMessage() gets called.
But processMyMessage() publishes again on "/my/channel", so the remote clients gets the second message.

This raises the question of why processMyMessage() does not get called recursively ad infinitum ?
The CometD Server detects that the sending client (the first argument to the publish() call) is the client associated with the sending Bayeux service, and avoids the infinite recursion.
Had you put remote instead of getClient() as first argument of publish(), you would have infinitely recursed.

Solutions to this problem are:

  • the JavaScript client should use a service channel to communicate to the Bayeux server
  • the processMyMessage() method uses a different channel to publish the data

The most common solution is to use a service channel.