jetty - 将 cometd session 与 HTTP session 配对

标签 jetty cometd

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

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

Cookie: jsessionid=758E2FAD7C199D722DA8B5E243E0E27D

基于 Simone Bordet 的帖子 here似乎推荐的解决方案是在我们正在做的 Cometd 握手期间传递这个 token 。

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

最佳答案

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

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

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

您可以通过注册 HttpSessionListener 来链接两个 session 。到HttpSession这样当它被销毁时,您可以检索当前的 CometD ServerSession来自映射器并调用 ServerSession.disconnect()在上面。

反之亦然,因为 CometD 没有像 HttpSession 这样的不活动超时概念。拥有。它必须使用您自己的逻辑在应用程序中实现。

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

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

此监听器监视与客户端(和服务器)的显式断开连接 - 谨防重入。

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

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

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

关键点是映射器,HttpSessionListenerRemoveListener ,并了解这些组件的生命周期。
一旦你做到了这一点,你就可以编写正确的代码来为你的应用程序做正确的事情。

最后,请注意 CometD 具有与 HttpSession 交互的与传输无关的方式。通过 BayeuxContext 例如,您可以从 BayeuxServer.getContext() 获得.
我建议你也看看它,看看它是否可以简化事情,特别是检索存储在 HttpSession 中的 token 。 .

关于jetty - 将 cometd session 与 HTTP session 配对,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10820866/

相关文章:

jetty - 如何在 Ubuntu 16.04 中为 CKAN 设置 jetty.home

jsp - 由jetty runner启动的Web应用程序不使用jSTL标签?

Grails 与 Comet 工作示例

tomcat - 我的 cometd 过滤器应该使用哪个 servlet-api jar

java - 在 dropwizard 中使用 cometd

maven - Jetty注解超时原因

java - 如何在 jar 中设置 KeyStore 和 trustStore 路径

javascript - 在 Angular 2 中处理 CometD channel 不起作用

java - CometD 将消息发布回客户端

java - org.apache.catalina.core.ContainerBase : A child container failed during start