Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LCDS & Flex - Preventing DuplicateHTTPSession errors after logout

I have a flex/LCDS stack, where I'm finding that after logout, I often (but not always) start receiving Duplicate HTTP Session errors on the client.

Here's the important facts of the stack:

  • The flex client has a login/logout functionality within the app. The page does not refresh after the logout. (Therefore, the Flex app, and the underlying mx.messaging.FlexClient remains initialised)
  • A user may have multiple tabs open.
  • per-client-authentication is set to false - we're trying to achieve SSO (integrating with CAS) so the user principle is bound to the JSession.
  • The problem is most evident when using long-polling for messaging, and when there are two (or more) tabs open.
  • The problem is very difficult to reproduce when using RTMP or Streaming channels.
  • A user is bound to a JSession - ie., if they log in on Tab1, they become logged in on Tab2.
  • When a user logs out from either tab, the Jsession is invalidated.

Here's my current theory as to what's causing the issue:

  • Tab1 (T1) Starts client -> Issued ClientId1 (C1) -> JSession1 (J1) created
  • Tab2 (T2) Starts Client -> Issued ClientId2 (C2) -> Joins J1
  • T1 logs in -> J1 Unaffected
  • T2 logs in -> J1 Unaffected
  • T1 & T2 Both subscribe, start polling over amflongpolling
  • T1 sends logout -> J1 Invalidated -> J2 created
  • T2 sends poll (against J1)
  • T1 logout completes, returns with J2, updates cookie

The last two calls create a conflict, where the LCDS sees the FlexClient appears to be related to 2 JSessions.

As a result, an error along the lines of the following is recieved:

Server.Processing.DuplicateSessionDetected Detected duplicate HTTP-based FlexSessions, generally due to the remote host disabling session cookies. Session cookies must be enabled to manage the client connection correctly.

Note: I've been able to recreate the problem in a stand-alone project. I believe it's not an issue with our application specific code, instead caused by the Stateful / session nature and conflicts between multiple tabs sharing the same session.

In summary, I believe the issue is caused where the session is invalidated on the server as a result of calls from one tab, but before the response is sent to the browser to inform it of the new JSession, calls are issued under the old Jsession.

What are some appropriate strategies to defend against this duplicate session issue?


Update

To clarify, while the scenario is similar to those discussed here, there are subtle differences which make the solutions in that article inappropriate.

Specifically, the article discusses preventing duplicate sessions by controlling the initial creation of JSessions across both browsers, using a JSP, or an orchestrated RemoteObject call.

Flex actually assists in this process by preventing outbound RemoteObject calls until the local FlexClient DSid variable is defined, showing that the initial session has been established.

My scenario differs, because the JSession (& associated LCDS FlexSession / Client-Side FlexClient objects) have already been established once, (using the techniques discussed in that article) and subsequently invalidated via logout - which calls session.invalidate() - destroying the JSession.

The issue arises when Tab2 sends a call with a stale JSession, a duplicate HTTP Session error. The situation then gets compounded, as when LCDS throw the DuplicateHTTPSession error, it also invalidates all known Jsessions attached with the client, meaning that the Tab1 - which had been ok - now has a stale JSession. The next time that Tab1 sends a call, IT causes a DuplicateHTTPSession error, and the cycle repeats.

Unfortunately, the Flex framework hooks for delaying calls while sesssions are established have no easy way (that I've found) of being re-enabled once set. (I've tried the following, to no avail:)

 // Reset DSid to get a new FlexSession established on LCDS
   use namespace mx_internal

   public function resetFlexSession()
   {
        FlexClient.getInstance().id = null;  
        // Note - using FlexClient.NULL_ID also doesn't work.
   }
like image 563
Marty Pitt Avatar asked Nov 14 '22 14:11

Marty Pitt


1 Answers

I feel for you - I've fought this for a long time and never found a solution, but found a fix that worked for me so hopefully it will at least keep this issue under control until you can find the culprit. (And if you do, please post it here).

Now, I've got a slightly different environment than you (I'm using CF on the backend) so keep that in mind.

I also tried the whole "FlexClient.getInstance().id = null;" thing too and it didn't work by itself, but it was how and where I implemented it that made it work.

So, this is what I did that made the problem go away.

On my main form, before ANY RemoteServer calls are made, I setup a creationComplete handler and placed this code you already know and love:

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

Next, in my very first call to the server, I gracefully handle the failure, and clear that stinking ID out again:

    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);
                }
        });

    }

And it worked.

Basically, try the call, and if it fails for the duplicate session thing, then clear out that ID and reissue the call.

The key point being that I don't think clearing out the ID works until you've made at least one call to the server. Once you do, it worked like a CHARM for me, and in all of my apps.

Note that I'm using the SWIZ framework above so just translate it to your own world.

By the way, I've never seen this error in any other browser but IE, and I believe it may have something to do with the infamous Dead Tab Issue that IE suffers from.

If the above doesn't work, I also know of a few changes to some config files on the server that might help.

Good luck my friend!

like image 135
PRB Avatar answered Dec 08 '22 00:12

PRB