Skip navigation.

org.cometd.Bayeux

Java Server Cometd API: Bayeux

The org.cometd.Bayeux interface is the central object that manages remote Cometd clients (or, better, their server-side counterpart) and channels.
One only of these objects exist for each web application, and it is created by the ContinuationCometdServlet, and put in the web application ServletContext to be accessed by other server side components.
See also the services section for how to retrieve and integrate the Bayeux object in your web application.

We have seen in the authorization section, how it is possible to use

Bayeux.setSecurityPolicy(SecurityPolicy policy)

to set the security policy for the Bayeux object, so that we can have full control on the authorization bits.

Another useful method is

Bayeux.getChannel(String channel, boolean create)

which allows to retrieve, and eventually create, a channel on which it is possible to publish messages, that will be received by all remote clients subscribed to that channel.
For example, imagine an online game where a player acts and we need to tell other players what that player did.
The acting player will communicate to the server its action, and the server will forward the action to other players:

public class GameService extends BayeuxService
{
    ...
    public void processPlayerAction(Client remote, Message message)
    {
        // Forward the action to other players
        Channel channel = getBayeux().getChannel("/dungeons/blue_cavern", false);
        channel.publish(getClient(), message.getData(), null);
    }
    ...
}

Sometimes, however, we need to send a message to a very specific client.
Imagine you're chatting with a friend, and you both logged in with your credentials at an imaginary site called www.bayeux-chat.org.
When you registered at www.bayeux-chat.org, the application stored your information in a database row with userId=100, and your friend was registered with userId=200.
When you connect to www.bayeux-chat.org to chat with your friend, you also have a Bayeux clientId=1234ABCD, while your friend has a Bayeux clientId=5678EFGH; you decide to start chatting privately with your friend.
Your chat message needs to contain an identifier of your friend (so the server will know to whom, of the thousands client connected, send your message), let's say it's the database's userId=200, but to deliver him your message, the server has to find the server-side Bayeux client object that represents your friend, and can do that using a mapping from userIds to clientId, and

Bayeux.getClient(String clientId)

in the following way:

public class ChatService extends BayeuxService
{
    ...
    public void processPrivateChat(Client remote, Map<String, Object> data)
    {
        // Extract the userId
        String friendUserId = (String)data.get("friendUserId");

        // Do not forget to check if that friendUserId is really your friend !

        // Map the database userId to a Bayeux clientId via some other service
        String friendClientId = this.userToClientMapper.get(friendUserId);
        
        Client remoteFriend = getBayeux().getClient(friendClientId);
        remoteFriend.deliver(getClient(), "/chat-room/1", data, null);
    }
    ...
}

How you map userIds to clientIds it's project dependent, but you can find some ideas in the authentication section.

Furthermore, it is possible to obtain the current HttpServletRequest from the Bayeux object via

Bayeux.getCurrentRequest()

This method returns null by default, unless the requestAvailable configuration parameter is set to true, see the configuration section.
From the HttpServletRequest it is possible to obtain the HttpSession, the ServletContext, etc. for any need you may have to interact with the servlet API.

Lastly, it is possible to add extensions to the Bayeux object, that will affect all clients, via:

Bayeux.addExtension(Extension)
Bayeux.removeExtension(Extension)

For a discussion about extensions, see here.