PHP - how to detect broken session end datetime?
Usercase: I need to track the user's duration on the site. This is calculated as (end datetime - start datetime). This works fine if the user clicks signout. then the system can record the end datetime. But I am issue in the edge cases: User's session ends due to - loss of internet connection at user's end, browser cl开发者_开发知识库osed, system went down, etc. In these cases how will the system know the end datetime so I can calculate the duration.Need the end datetime to be calculated as close as possible to the real datetime. If this is not possible then upto 5 mins of accurate is fine.
One possible way i see is the keep pinging the client system and check if active or not. But I dont want to do this as it adds unwanted bandwidth. So any other way to get this info for the edge cases?
Why not just check the time of the last pageview?
Checking the browser window open-time won't do much for people like me who like to leave tabs open... Not to mention it will be quite hard to cover all of the edge-cases (browsers that don't support JS, people behind proxies, etc). The last pageview should be accurate to a few minutes, and it will have the least overhead/complexity while still maintaining decent level of accuracy...
In practice the system can't ever know the end time, because HTTP is fundamentally a stateless protocol. PHP sessions (and similar features in other web scripting languages) are a hack to implement something that seems stateful but such hacks can't fully overcome the stateless nature of HTTP. For example, as you've discovered, there's no way for the server to know that the user logged out if they didn't go through a "log out" process.
You could use AJAX to ping the user, but as you said, this uses bandwidth. It would also fail to function if the user has javascript support turned off.
The only other sensible option is to log a timestamp for a user every time they land on a page in your system and look at how long it's been since the timestamp had updated. If it exceeds a reasonable limit, say 20 minutes, then you can make the assumption that the user is no longer on your site. Again, this isn't totally ideal as the user might have just gone out for a smoke or something, but as HTTP is stateless no solution you can implement is entirely ideal.
Track the last activity time of the user session - basically on each client request you update your session record with the time of the request. If you've also stored the login time then you can always calculate the length of the session whether it's active, inactive or the user has logged out. I also put a 'logged_out' flag on my session tables which gets set if the user actively logs out.
Here's the definition of my session table:
CREATE TABLE IF NOT EXISTS `session` (
`id` int(11) NOT NULL auto_increment,
`php_session_id` varchar(100) NOT NULL default '',
`ip_addr` varchar(100) NOT NULL default '',
`login_time` datetime NOT NULL ,
`activity_time` datetime NOT NULL ,
`user_id` int(11) NOT NULL default '0',
`logged_out` tinyint(1) NOT NULL default '0',
PRIMARY KEY (`id`),
KEY `session_id` (`php_session_id`,`ip_addr`),
KEY `user` (`user_id`,`logged_out`)
) ;
精彩评论