The HTTP session and the CometD sessions have different lifecycles: for example, if there is a temporary connection failure, the CometD session will fail, and the server will ask to the client to re-handshake, thus creating a different CometD session (representing the same user, but with a different CometD clientId
). In the same case, the HttpSession
will remain the same.
Having this in mind, you need to maintain - at the application level - a mapping between a username, the correspondent HttpSession
, and the correspondent ServerSession
.
Let's call this mapping HttpCometDMapper
.
Every time a new user logs in, you register its name (or another unique identifier of the user), the HttpSession
, and the current ServerSession
.
Probably you will need a two step process, where you first link the username and the HttpSession
, and then the same username with the ServerSession
.
If a CometD re-handshake is performed, you update the mapper with the new ServerSession
.
You can link the two sessions by registering an HttpSessionListener
to the HttpSession
so that when it's destroyed, you retrieve the current CometD ServerSession
from the mapper and call ServerSession.disconnect()
on it.
The viceversa is a bit trickier because CometD does not have a concept of inactivity timeout like HttpSession
has. It must be implemented in the application with your own logic.
One part of doing it is to register a RemoveListener
on the ServerSession
, like that:
serverSession.addListener(new ServerSession.RemoveListener()
{
public void removed(ServerSession session, boolean timeout);
{
if (!timeout)
{
// Explicitly disconnected, invalidate the HttpSession
httpCometDMapper.invalidate(session);
}
}
});
This listener watches for explicit disconnects from the client (and the server - beware of reentrancy).
Slightly more difficult is to implement the same mechanism for non-explicit disconnects. In this case, the timeout
parameter will be true, but could have happened because of a temporary network failure (as opposed to the client disappearing for good), and the same user may have already re-handshaken with a new ServerSession
.
I think in this case an application timeout could solve the issue: when you see a ServerSession
removed because of a timeout, you note that user and start an application timeout. If the same user re-handshakes, cancel the application timeout; otherwise the user is really gone, the application timeout expires, and you invalidate the HttpSession
too.
What above are just ideas and suggestions; the actual implementation depends heavily on application details (and that's why is not provided by CometD out of the box).
The key points are the mapper, the HttpSessionListener
and the RemoveListener
, and knowing the lifecycles of those components.
Once you manage that, you can write the right code that does the right thing for your application.
Finally, note that CometD has a transport-agnostic way of interacting with the HttpSession
via the BayeuxContext
instance, that you can obtain from BayeuxServer.getContext()
.
I suggest that you look at that also, to see if it can simplify things, especially for retrieving tokens stored in the HttpSession
.