6

当用户的会话超时发生时,我正在尝试注销用户。注销用户 - 在我的情况下 - 需要修改用户在数据库中的“在线”状态。
我在想我也许可以使用观察者模式来制作一些东西来监视用户会话的状态并在会话到期时触发回调——这将保留用户的名称,以便我们可以更新数据库。我不确定在会话方面从哪里开始。我可以将回调绑定到会话的超时吗?

这些东西是否内置在任何可用的 pear 或 zend 会话包中?我会用我必须做的一切来实现这一点!



UPDATE @ 16:33:
如果您有一个用户可以相互交互的系统(但他们只能与在线用户交互)怎么办?用户需要知道当前还有哪些其他用户在线。

如果我们只是在每次页面刷新时检查会话是否仍处于活动状态,那么在超时后,用户将被发送到未登录的页面,但他们仍然在系统中列为在线。

这种方法很好,只是当我们超时会话时,我们会丢失有关可用于注销用户的用户信息。



更新@16:56:
对。谢谢。我同意……有点丑陋。我已经对服务器进行了一些缓慢的轮询,因此实现该方法非常容易。对于会话处理包来说,这似乎是一个非常有用的功能。Zend 和 PEAR 都有会话包。

4

6 回答 6

2

每当用户点击页面时,在数据库中标记该时间,调用此列 LastAccessed。当用户单击站点的注销部分时,您可以将此值设置为 null。在编写查询以查找当前登录的用户列表时,请执行以下操作:

SELECT *  FROM Users WHERE LoggedIn=1 AND LastAccess > DATEADD(Minute,-20.GETDATE())

这将返回仍然具有活动会话的用户。请原谅可能不适用于 MySQL/PHP 的 SQL,但这应该会给您一个大致的概念。

于 2008-10-29T17:29:01.453 回答
2

先看最简单的情况。假设您的系统上有 1 个用户,并且您希望他们的会话超时,并且您希望准确报告他们的状态。用户在 12 分钟内没有访问过页面,您的会话超时设置为 10 分钟。会发生两件事之一。他们要么会在短时间内再次访问,要么不会。如果他们不再访问,系统将如何运行代码来更新他们的超时状态?唯一的方法*是让一个单独的进程为当前处于“会话中”状态的所有用户启动状态更新功能。

每次用户访问您的站点时,更新数据库中的变量,将他们的会话与上次访问时间相关联。然后创建一个每分钟运行的 cron 作业。它调用一个简单的函数来检查会话状态。任何早于超时期限的会话都将设置为“超时”状态。(您还应该在超时会话坐了一段时间后清理桌子)。如果您想要关于登录人数的报告,请查询上次访问时间晚于超时间隔开始的所有记录。

"*" 还有其他方法,但对于简单的 Web 应用程序而言,它并不是真正需要的。如果您有比简单的网络应用程序更复杂的东西,请更新您的问题以反映特定需求。

于 2008-10-29T16:55:46.247 回答
1

你为什么要这样做?常见的方法是检查用户发送的每个请求是否超时。当然,这意味着您的数据库中的状态不是最新的,因为即使已达到超时,用户仍显示为已登录。

但出于实际目的,这通常无关紧要。

于 2008-10-29T16:28:05.120 回答
0

丑陋但也许可行的建议:

向页面添加一个异步保持活动请求者,以更新它们的最后活动时间戳。然后,如果用户的最后活动时间戳超过 20 秒,您可以有一个将用户标记为离线的 cron 作业。将该 cron 作业设置为每分钟运行一次就可以了。我不确定是否有办法在用户会话超时或关闭浏览器时触发某些事情。

于 2008-10-29T16:47:07.967 回答
0

我的第一个想法是,您可以创建一个自定义会话处理程序,将登录解释为具有活动会话。

有关创建自定义会话处理程序的一些示例,请参阅http://www.daniweb.com/code/snippet43.html并阅读 PHP 文档http://ca.php.net/manual/en/function.session-set-保存处理程序.php

于 2008-10-29T17:04:47.027 回答
0

我知道这可能是一个较老的问题,但您的问题的“最佳”答案可以在这里找到:http: //www.codeguru.com/forum/archive/index.php/t-372050.html

它是这样说的: php.ini 文件包含一个名为 sesison.save_path 的设置,它决定了 PHP 将包含会话数据的文件放在哪里。一旦会话过时,PHP 将在下一次垃圾回收期间将其删除。因此,对该会话是否存在字段的测试应该足以确定该会话是否仍然有效。

$session_id = 'session_id';
$save_path = ini_get('session.save_path');

if (! $save_path) {
$save_path = '.'; // if this vlaue is blank, it defaults to the current directory
}

if (file_exists($save_path . '/sess_' $session_id)) {
unlink($session_id); // or whatever your file is called
}
于 2011-10-12T04:35:27.473 回答