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:
mx.messaging.FlexClient
remains initialised)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.Here's my current theory as to what's causing the issue:
amflongpolling
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?
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.
}
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With