LCDS& Flex - 注销后防止DuplicateHTTPSession错误

时间:2011-11-18 05:30:06

标签: flex blazeds lcds

我有一个flex / LCDS堆栈,我发现在注销后,我经常(但并不总是)在客户端上开始收到Duplicate HTTP Session错误。

这是堆栈的重要事实:

  • Flex客户端在应用程序中具有登录/注销功能。注销后页面不刷新。 (因此,Flex应用程序和基础mx.messaging.FlexClient仍然初始化)
  • 用户可能打开多个标签页。
  • per-client-authentication设置为false - 我们正在尝试实现SSO(与CAS集成),因此用户原则绑定到JSession。
  • 当使用长轮询进行消息传递时,以及打开两个(或更多)选项卡时,问题最为明显。
  • 使用RTMP或流媒体频道时,很难重现此问题。
  • 用户绑定到JSession - 即,如果他们在Tab1上登录,他们将登录到Tab2。
  • 当用户从任一选项卡注销时,Jsession无效。

这是我目前关于造成这个问题的理论:

  • Tab1(T1)启动客户端 - >已发布ClientId1(C1) - > JSession1(J1)创建了
  • Tab2(T2)启动客户端 - >发布ClientId2(C2) - >加入J1
  • T1登录 - > J1未受影响
  • T2登录 - > J1未受影响
  • T1& T2都订阅,开始轮询amflongpolling
  • T1发送注销 - > J1无效 - > J2创建了
  • T2发送投票(针对J1)
  • T1退出完成,返回J2,更新Cookie

最后两次调用产生冲突,LCDS看到FlexClient似乎与2个JSessions相关。

结果,收到了以下错误:

  

Server.Processing.DuplicateSessionDetected检测到重复   基于HTTP的FlexSessions,通常是由于远程主机禁用   会话cookie。必须启用会话cookie才能管理客户端   连接正确。

注意:我已经能够在独立项目中重新创建问题。我认为这不是我们的应用程序特定代码的问题,而是由共享同一会话的多个选项卡之间的有状态/会话性质和冲突。

总之,我认为问题是由于来自一个选项卡的调用导致服务器上的会话无效,但是在将响应发送到浏览器以通知新的JSession之前,调用是在旧的Jsession。

有哪些合适的策略可以防止此重复的会话问题?


更新

澄清一下,虽然情景类似于所讨论的情况here,但存在微妙的差异,使得该文章中的解决方案不合适。

具体来说,本文讨论了通过使用JSP或协调的RemoteObject调用跨两个浏览器控制JSessions的 初始创建 来防止重复会话。

Flex实际上通过阻止出站RemoteObject调用来协助此过程,直到定义了本地FlexClient DSid变量,表明初始会话已经建立。

我的场景有所不同,因为JSession(及相关的LCDS FlexSession /客户端FlexClient对象)已经建立一次(使用该文章中讨论的技术)并随后通过注销失效 - 调用{{1} - 破坏JSession。

当Tab2使用陈旧的JSession发送调用时出现问题,这是一个重复的HTTP会话错误。然后情况变得复杂,因为当LCDS抛出DuplicateHTTPSession错误时,它也使与客户端连接的所有已知Jsessions无效,这意味着Tab1 - 一直没问题 - 现在有一个陈旧的JSession。 Tab1下次发送呼叫时,IT会导致DuplicateHTTPSession错误,并且循环重复。

不幸的是,Flex框架挂钩用于在建立sesssions时延迟调用没有简单的方法(我已经发现)一旦设置就重新启用。 (我已尝试过以下内容,但无济于事:)

session.invalidate()

3 个答案:

答案 0 :(得分:1)

我觉得你 - 我已经打了很长时间并且从来没有找到解决方案,但找到了一个对我有用的修复,所以希望它至少能够控制这个问题直到你可以找到罪魁祸首。 (如果你这样做,请在这里发布)。

现在,我的环境与你的环境略有不同(我在后端使用CF),请记住这一点。

我也尝试了整个“FlexClient.getInstance()。id = null;”事情也没有本身,但它是如何 我实现它使它工作。

所以,这就是 I 所做的事情,这使问题消失了。

在我的主窗体上,在进行任何 RemoteServer调用之前,我设置了一个creationComplete处理程序,并放置了您已经知道和喜爱的代码:

// Not sure if this is needed anymore, but I'm leaving it in
FlexClient.getInstance().id = null;

接下来,在我对服务器的第一次调用中,我优雅地处理了失败,并再次清除了这个发臭的ID:

    public function login(event:Event): void {

        Swiz.executeServiceCall(roUsers.login(),
            function (event:ResultEvent): void {
                // Handle a successful login here...
            }
            , function (faultevent:FaultEvent): void {
                // This code fixes this issue with IE tabs dying and leaving Flex with a Duplicate Session problem.
                if (faultevent.fault.faultString.indexOf("duplicate")) {
                  FlexClient.getInstance().id = null;
                  Swiz.dispatchEvent(event);
                }
        });

    }

工作

基本上,尝试呼叫,如果重复会话事件失败,则清除该ID并重新发出呼叫。

关键是我认为在您至少拨打一次服务器之前清除ID无效。一旦你这样做,它对我来说就像一个CHARM,在我的应用程序的全部中。

请注意,我正在使用上面的SWIZ框架,因此只需将其转换为您自己的世界。

顺便说一下,除了IE之外,我从未在任何其他浏览器中看到过这个错误,我相信可能与IE所遭受的臭名昭着的死标签问题有关。

如果以上操作不起作用,我也知道服务器上某些配置文件的一些更改可能有所帮助。

祝你好运我的朋友!

答案 1 :(得分:0)

这篇标题为Avoiding duplicate session detected errors in LCDS的文章深入解释了您的情况。这是一个相关的引用:

  

... [LCDS]认为它收到的FlexClient已经是   与服务器上的不同会话相关联。

  为客户端应用程序确保FlexClients中的   应用程序不会进入这种糟糕的状态,客户端应用程序必须   确保之前已在服务器上建立会话   多个FlexClient同时连接到服务器。

有几种方法可以解决这个问题,包括:

  • 调用jsp页面加载应用程序
    "The jsp page could both create a session for the client application and return an html wrapper to the client which would load the swf."
  • 呼叫远程目的地
    "which would automatically create a session for the client application on the server"

答案 2 :(得分:0)

另外一个不相关的原因;

某些浏览器(例如Internet Explorer)将域命名规则应用于cookie,这意味着像#34; my_clientX.server.com"这样的代码域虽然可能会返回有效的BlazeDS响应,但会不断触发重复会话通知,因为访问cookie将被阻止。

将名称更改为有效名称(不带下划线)将解决此问题。