PHP - 如何检测损坏的会话结束日期时间?

发布于 2024-10-14 18:28:08 字数 297 浏览 5 评论 0原文

用户案例:我需要跟踪用户在网站上的持续时间。计算方式为(结束日期时间 - 开始日期时间)。如果用户单击注销,则效果很好。然后系统可以记录结束日期时间。但我在边缘情况下遇到问题: 用户会话结束的原因是 - 用户端互联网连接丢失、浏览器关闭、系统停机等。在这些情况下,系统如何知道结束日期时间,以便我可以计算持续时间。需要将结束日期时间计算为接近尽可能真实的日期时间。如果不可能,那么最多 5 分钟的准确度就可以了。

我看到的一种可能的方法是不断 ping 客户端系统并检查是否活动。但我不想这样做,因为它增加了不需要的带宽。那么还有其他方法可以获取边缘情况的信息吗?

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 closed, 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我很坚强 2024-10-21 18:28:08

为什么不只检查最后一次浏览量的时间呢?

检查浏览器窗口打开时间对于像我这样喜欢打开选项卡的人来说没有多大作用......更不用说覆盖所有边缘情况(不支持 JS 的浏览器,代理背后的人等)。最后的页面浏览量应该精确到几分钟,并且它将具有最少的开销/复杂性,同时仍然保持不错的准确性水平......

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...

相思故 2024-10-21 18:28:08

实际上,系统永远无法知道结束时间,因为 HTTP 本质上是一种无状态协议。 PHP 会话(以及其他 Web 脚本语言中的类似功能)是一种实现看似有状态的东西的 hack,但此类 hack 无法完全克服 HTTP 的无状态本质。例如,正如您所发现的,如果用户没有经历“注销”过程,服务器就无法知道用户已注销。

您可以使用 AJAX 来 ping 用户,但正如您所说,这会占用带宽。如果用户关闭了 javascript 支持,它也将无法运行。

唯一明智的选择是在用户每次登陆系统中的页面时记录用户的时间戳,并查看自时间戳更新以来已经过去了多长时间。如果超过合理限制(例如 20 分钟),则您可以假设用户不再访问您的网站。同样,这并不完全理想,因为用户可能刚刚出去抽烟或做其他事情,但由于 HTTP 是无状态的,您可以实现的任何解决方案都不是完全理想的。

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.

世态炎凉 2024-10-21 18:28:08

跟踪用户会话的最后活动时间 - 基本上在每个客户端请求上,您都会使用请求时间更新会话记录。如果您还存储了登录时间,那么您始终可以计算会话的长度,无论会话是活动的、非活动的还是用户已注销。我还在会话表上放置了一个“logged_out”标志,如果用户主动注销,该标志就会被设置。

这是我的会话表的定义:

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

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`)
) ;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文