tags:

views:

57

answers:

4

Hi,

Storing the session id on the client computer is no problem and is very straight forward. The problem is to store the actual session on the server until I'm actually feeling I'm done with it.

The garbage collector is pretty clear about how it works. I can see no way to prevent it from cleaning up the garbage within a certain time. I can set that time high, but then risking session hijacking (Which still is very small and hijacking the session would be of no greater use for a cracker) or having the session directory overcrowded (guess that you really need huge traffic for this to occur but still...)

Is the only solution to make regular http requests with javascript to prevent the GC to eventually grab the session if the client is idle?

Thanks in advance

+3  A: 

Pretty much yes. You can't reliably detect that the browser window has been closed. Even though JS offers on widow close event, you should not use it, as closing the browser by clicking 'close' button is only one of several ways the client session might end.

Other possibilities:

  1. Browser crashes
  2. Client's computer crashes
  3. Network connection dies
  4. Several browsers don't consider closing the window an unload event (Opera doesn't even consider closing a tab or moving away from a webpage by typing an address in the address bar an unloading event)
Mchl
The heart of the problem is that HTTP is a stateless protocol. (You may consider adding that. Or a reference to this statement, by... I forgot.)
MvanGeest
I'm not sure if you approached the problem from the right angle. I'm not necessarily in need of destroying the session "on close". It should eventually be cleaned away in a near future anyway, since it hasn't been read or updated for a while.I just want to prevent the session from being trashed while the browser is still running (That particular session of the browser of course)The fact that it might crash or other stupid things shouldn't be considered. There is no way to prevent Murphy from doing his job.
Anders
My point was, only reliable way of checking if there's still someone on the other side of connection is to talk to them.
Mchl
I think we can decide that sending a "ping" from the client to the server every now and then is the only solution then. Thanks for the help
Anders
@Mchl I think you meant the onunload event. If I'm mistaken, sorry :p I also fixed the list formatting.
Artefacto
I was not sure how this event is called, as I hardly ever use it. Thanks for edits.
Mchl
+1  A: 

If what you want is to keep the sessions forever, then define a custom garbage collector.

However, you have no real way to know when users close their browser. The easiest thing to do is to set up a JavaScript or META REFRESH pinger which will keep informing you as long as they have your page open - but you can't know they don't still have the browser open to a different page.

Borealid
I guess it doesn't matter if they have my page or another open. Are you referring to multiple tabs open or something? When they leave my site the javascript will stop pinging the server right? So that shouldn't be a concern as far as I can understand?
Anders
A: 

I believe you can use XMLHTTPRequest (Ajax Technology) to ping your server to, say, blank page with simple session_start(); Say, every fifteen minutes (default PHP session timeout is 20 seconds) so they don't overload your server.

But, if you do really want to have persist data, a cookie with no explicit expired time are being cleaned on browser exit, so you can store a storage key in cookie. This have one advantage over session -- if client's network connection dies, the session is still working. But this risks more of the session hijacking.

If you are talking about keeping login persists within a browser session, a cookie way is preferred, and is in used by many sites around the world, including Drupal, Wordpress and Joomla! CMS.

Nat
Thanks for the answer Nat. About that last part. Are you talking about storing log in details in the cookie or merely session-id in the cookie. I got a little confused. You have a link to an article or tutorial covering using cookie instead of a session for log in purpose?
Anders
A: 

There are many ways, which none of them are desireable. I will list out what I learn. Note: I hope people understand this. Most people assume I want to logout only when client close browser. That's not the case, I just want to free up resources instead of 20minute lag. Most devs just upgrade computer I guess.

1) Keep ping your server from client script, thus, it will keep the "short session" alive. This is obviously will increase traffic to your server and it will obviously not logout instantly as you don't want to ping like every second.

2) Use Javascript from client broswer. So far, I don't think any of them is working, even the existing example of IE code, the clienX will be > 0. Anyway, here is the code that works for me so far. Only on IE since Firefox event is not working for me right now. I roughly calculated the position of the close button relatively on the screen and determine if client clicked i that area. If refresh button is too close to close button (x wise), it will think you clicked close button, but, that's a rare case.

<head runat="server">
    <title>Untitled Page</title>
<script type="text/javascript">
    function test(event) {
        var X = window.event ? window.event.screenX : event.clientX;

        // IE only because event.clientX for FF = undefined (event.clientX IS the FF way).
        if (X == null) {
            alert("No X");
            return;
        }

        var left = window.screenLeft ? window.screenLeft : window.screenX;
        var winwidth = document.body.clientWidth ? document.body.clientWidth : window.outerWidth;
        var leftMargin = document.body.leftMargin ? parseInt(document.body.leftMargin, 10) : 0;
        var rightMargin = document.body.rightMargin ? parseInt(document.body.rightMargin, 10) : 0;
        var resultX = X - (window.screenLeft + winwidth + leftMargin + rightMargin); // scroll bar width is not calculated.
        var Y = window.event ? window.event.clientY : event.clientY;

        if (resultX > -25 && Y < 0)
            alert("logging out");
    };
</script>

</head>
<body onbeforeunload="test(event);">