使用HTTP会话配对cometd会话

Lig*_*ard 6 jetty cometd

我们有一个使用Jetty 8.1,dojo和cometd的Web应用程序,它使用(1)JSON/HTTP REST API进行同步操作和(2)cometd API从服务器接收大量事件,在浏览器和Web容器之间进行交互.

我们还不完全清楚的是如何优雅地管理这两种不同API的认证会话,特别是因为我们将尽可能使用websocket而不是常规HTTP.该应用程序使用标准Jetty LDAP模块使用基于表单的身份验证.因此,从HTTP角度来看,容器为浏览器提供了标准的jsessionid,如下所示:

Cookie: jsessionid=758E2FAD7C199D722DA8B5E243E0E27D
Run Code Online (Sandbox Code Playgroud)

基于西蒙娜博尔德的帖子在这里似乎推荐的解决方案是的cometd握手这就是我们正在做的过程中通过此令牌.

我们遇到的问题是有两个根本不同的会话 - HTTP会话和Bayeux cometd会话.由于潜在的内存泄漏和安全问题等原因,我们希望它们一致终止或"配对".如果用户的HTTP会话终止,我们希望相应的Bayeux会话也终止,反之亦然.有推荐的方法吗?

sbo*_*det 11

HTTP会话和CometD会话具有不同的生命周期:例如,如果存在临时连接失败,则CometD会话将失败,并且服务器将要求客户端重新握手,从而创建不同的CometD会话(表示相同的用户,但使用不同的CometD clientId).在同样的情况下,HttpSession意志保持不变.

考虑到这一点,您需要在应用程序级别维护用户名,通讯员HttpSession和通讯员之间的映射ServerSession.我们称这个映射HttpCometDMapper.每次新用户登录时,都会注册其名称(或用户的另一个唯一标识符),HttpSession当前和ServerSession.可能你需要一个两步的过程,你首先链接用户名和HttpSession,然后用相同的用户名链接ServerSession.

如果执行CometD重新握手,则使用new更新映射器ServerSession.

你可以通过注册一个HttpSessionListener来链接这两个会话,HttpSession这样当它被销毁时,你ServerSession从mapper中检索当前的CometD 并调用ServerSession.disconnect()它.

反之亦然有点棘手,因为CometD没有像had那样的非活动超时概念HttpSession.必须使用您自己的逻辑在应用程序中实现它.

这样做的一个部分是注册RemoveListenerServerSession,这样的:

serverSession.addListener(new ServerSession.RemoveListener() 
{
    public void removed(ServerSession session, boolean timeout);
    {
        if (!timeout)
        {
            // Explicitly disconnected, invalidate the HttpSession
            httpCometDMapper.invalidate(session);
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

此监听器监视与客户端(以及服务器 - 显示可重入)的显式断开连接.

稍微更困难的是为非显式断开连接实现相同的机制.在这种情况下,timeout参数将为true,但可能由于临时网络故障而发生(与客户端正常消失相反),并且同一用户可能已经与新的重新握手ServerSession.

我认为在这种情况下,应用程序超时可以解决问题:当您看到ServerSession因超时而被删除时,您会注意到该用户并启动应用程序超时.如果同一用户重新握手,则取消应用程序超时; 否则用户真的不见了,应用程序超时到期,你也失效了HttpSession.

以上只是想法和建议; 实际的实现在很大程度上取决于应用程序的细节(这就是为什么CometD不提供开箱即用的原因).

关键点是mapper,the HttpSessionListener和the RemoveListener,以及了解这些组件的生命周期.管理完成后,您可以编写正确的代码,为您的应用程序做正确的事情.

最后,要注意的cometd与交互与传输无关的方式HttpSession通过的BayeuxContext情况下,您可以从获得BayeuxServer.getContext().我建议你也看一下,看它是否可以简化一些事情,特别是对于检索存储在其中的令牌HttpSession.