Disclaimer: This is more academic than anything. Ideally you'd want to avoid a design that is flawed with respect to multiple sessions. Careful consideration for this, up front, should be taken to avoid needing a band-aid such as this.
I'm sure we've all worked on, or are aware of web applications (especially in the enterprise) that have tightly bound themselves to the server session. In these cases, it's possible that the session will become corrupted if more than one browser session is open and using the same server session cookie.
I've examined all of the options and found the best way to move forward would be to discourage the use of multiple browser sessions that share a server session cookie. This is only really a problem when a user executes "New Window - Ctrl+N" in IE or the equivalent of "duplicate tab" in other browsers. Essentially we end up with two active browser sessions sharing the same cookies.
So, to discourage this, as it will likely be inadvertent, some kind of warning system should be in place to prevent this behavior. Now, the underlying code should do plenty of concurrency checking to ensure data integrity, but there are some situations where issues can result from viewstate corruption.
A solution that I came to, after finding that the general answer is "it's impossible", was to rely on AJAX to send out "pings" and measure the time between. So, we have a general rule: we "ping" at a certain interval and if the delta between the last ping in the current ping is *less* than the ping duration, we know we have multiple active browser sessions on a single server session.
So, where
Pf is ping frequency;
Pc is current ping; and
Pl is last ping, then we have an error when
Pf > (
Pc -
Pl).
p1 p2 p3 p4
TAB1 0-----|-----|-----|-----|---...
: : :
: p1 : p2 : p3 p4
TAB2 0-----|-----|-----|-----|---...
^ ^ ^ ^ ^ ^ ^ ^
Deltas
----+---+------------
TAB | P | Delta (Pc - Pl)
----+---+------------
1 | 1 | 5
1 | 2 | 5
2 | 1 | 2.5 -Error
1 | 3 | 2.5 -Error
2 | 2 | 2.5 -Error
Now, if there is network congestion or other factors, then the delta will be
greater than the frequency, ruling out false-positives.
We do have a problem if two tabs are open at the exact same momemnt. But, since the ping frequency is just the frequency at which the requests are made, and not a guaranteed elapsed time, we can assume that soon the two browser sessions will begin sliding out of sync.
In the example, I have the ping frequency set to every 5 seconds. If there are 100 simultaneous users then we're looking at ~20 requests/second for the ping Servlet/HttpModule. To minimize unnecessary network traffic I was thinking that the ping frequency would decay as time went on until a maximum of 20 pings/second was reached. This would amount to ~5 requests/second with 100 concurrent users. This is a trade-off, though, as it will cause a delay in detection. However, once detection occurs, the frequency resets to 5 pings/second until resolved. (These numbers are just as an example; they would vary a based on the environment)
To minimize concurrency and scalability issues, the last ping timestamp for the session should be kept in the session itself. This will allow any distributed session technology to maintain the availability of the session across JVMs or app domains without our ping service needing to be aware of it.