定时自动注销和浏览器关闭
Posted
技术标签:
【中文标题】定时自动注销和浏览器关闭【英文标题】:timed auto logout and browser close 【发布时间】:2011-09-12 20:07:26 【问题描述】:我创建了一个非常简单的多用户游戏用于学习目的。
当用户登录时,每个其他用户都会获得所有当前登录用户的更新。
当用户登录时,它只是将该用户在 SQL 数据库中的值设置为 1。当他们注销时,该值应为 0。
我正在使用 $(window).unload(function() );试图捕捉标签/浏览器关闭,但它只能工作。
两个问题:
有没有更好的方法让浏览器或标签页关闭?
如果它错过了标签关闭,或者他们的机器崩溃,或者互联网连接中断,或者用户只是离开机器,我想继续并自动将它们注销。
我正在使用带有 php 后端的 html/Jquery 前端。我该怎么做才能完成第二个问题?我假设我需要用 PHP 来做这件事。我们假设浏览器可能不再存在,因此不处理 jquery 的东西。 PHP 可以在一个连续的计时器上做一些事情来检查用户是否还在附近...而不是简单地让用户每 10 秒点击一个按钮?
编辑: 这里有一个潜在的解决方案:How to detect if a user has logged out, in php? 但我使用 ajax 来避免页面刷新。理想情况下,用户从不 f5 页面,或单击任何按钮(我正在测试,请记住,这不是真正的应用程序)。 PHP 会在不刷新整个页面的情况下查看最后一个活动吗?
编辑2: 我已将以下代码添加到我的 PHP 中,并使用 setInterval 使用相应的 jquery 函数
if (isset ($_POST['keepalive']))
if (filter_input(INPUT_POST,'keepalive') == '1')
$name = $_SESSION['name'];
$time = time();
mysql_query("UPDATE tictac_names SET keep_alive = '$time' WHERE name ='$name'") or die(mysql_error());
这会在我的表中插入一个 unix epoc 时间戳,这对于简单的计算来说非常容易。
我现在的问题是:我如何告诉 PHP 在 X 秒内对每个登录用户运行一次检查?我的 PHP 后端文件主要设置为捕获 post 变量并运行代码,然后将其交给 jquery。由于此代码旨在注销不活动的浏览器/用户,因此我不能依赖 jquery 向 PHP 发送请求,并且没有刷新 PHP。我是否需要做一些 cron 工作或一些奇怪的事情来让 PHP 检查所有在最后 X 秒内没有更新的用户?
救命!
【问题讨论】:
【参考方案1】:不知道第一个问题,但是关于第二个问题的建议如何:
当用户处于“活跃”状态时,他们是否会相当频繁地引发页面请求?如果是这样,您可以拥有一个系统,通过该系统,登录用户会定期登录您的 SQL 数据库,并带有时间戳。然后让另一个脚本查找所有那些时间戳早于指定时间段(无论您喜欢什么,例如 10 秒)的用户,并将它们设置为“0”。
我可以建议一些代码,但也许这不是您想要的 - 请告诉我。
编辑:好的,您编辑的链接似乎已经用与我刚才建议的类似的系统得到了回答。如果您使用 AJAX,您可以在后台定期调用 php 脚本来设置和检查 SQL 表中的时间戳。
【讨论】:
【参考方案2】:您可以实现基于 $_SESSION 的解决方案,例如 Gumbo answered this question。然后你可以调整它来处理你的数据库需求。
【讨论】:
【参考方案3】:如果您使用 html5 套接字连接作为连接服务器的方式,您的套接字服务器脚本会知道订阅者何时断开连接。这也将允许您将数据实时推送到所有客户端,而无需长时间轮询。唯一的问题是我现在不知道 html5 套接字的支持是什么。我使用 Flash 做过类似的事情,它也支持套接字连接。
【讨论】:
查看 tenthtower.com 以了解实际情况。【参考方案4】:不只是在用户登录时设置一个标志,而是记录一个时间戳,您可以使用它来确定登录时间。此外,你可以让你的客户端,call-home 使用 AJAX 一些 PHP 脚本来在数据库中保存最后一个用户活动的时间戳。
然后您可以使用服务器中的 cron 作业定期执行会话清理脚本。该脚本将查询数据库以检测过时的会话并进行注销(将已登录标志设置为 0)。如果服务器安装了 PHP CLI(命令行界面),您可以在 PHP 中编写脚本。
【讨论】:
【参考方案5】:仅捕获关闭窗口后返回站点的用户的一种可能方法是使用数据库获取用户 ID、IP 和时间,如下所示:
$_SESSION['ip'] = $_SERVER['HTTP_CLIENT_IP'];
if(isset($_SESSION['ip']))
if(Logedin) // This login detection can be set by cookies can very depending on situation
mysql_query("INSERT INTO users SET user_login=\"".'1'."\",user_id=\"".$idfromlogin."\",user_ip=\"".$_SESSION['ip']."\",user_time=\"".time();."\"");
然后,如果用户通过“X”按钮关闭窗口会话结束,那么我们可以在每次页面加载时针对time();
进行检查。现在我们必须开始一个新会话,但这就是我们将时间保存在数据库中的原因。
$_SESSION['ip'] = $_SERVER['HTTP_CLIENT_IP'];
if(isset($_SESSION['ip']))
if (!$sql = mysql_query("SELECT * FROM users WHERE user_ip=".$_SESSION['ip']))
die('Error: ' . mysql_error());
$row = mysql_fetch_array($sql);
if ($row['user_time'] + 10 * 60 < time()) // this is 10 minutes have passed
// now to find the user database by the session database the logins is your method of loging in a user from logins database with pass and name
if (!$user = mysql_query("UPDATE logins SET user_isloggedin=\"".'0'."\" WHERE user_id=".$row['user_id'])) //from the users database
die('Error: ' . mysql_error());
这仅显示了一种检查 IP 的方法,如果他们回来了并且记录的时间已经过去了。这没有显示当有人按下“X”按钮时如何捕捉。 IP 可以改变,所以我会写一个检查 IP 函数:
function getRealIpAddr()
if (!empty($_SERVER['HTTP_CLIENT_IP'])) //check IP from share internet
$ip=$_SERVER['HTTP_CLIENT_IP'];
elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) //to check IP is pass from proxy
$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
else
$ip=$_SERVER['REMOTE_ADDR'];
return $ip;
【讨论】:
【参考方案6】:我假设,用户在注销时显示为在线和离线。销毁会话或 cookie 需要客户端浏览器处于工作模式。
解决方案
我还假设维护了一个时间戳列。设置一个时间间隔来检查当前 TS 和 Last Timestamp 之间的时间间隔。同时根据你的 id 更新你自己的 TS 到当前的 TS。
setInterval(function()
$.ajax(
url: "/backend.php?userid=id",
success: function(resoponse)
console.log(response);
);
, 10000);
后端.php
$user_id = $_GET["userid"];
$query = "select * from table name where (GETDATE() - timestamp) > 60";
$resut = mysqli_query($con, $query);
while($row = mysqli_fetch_assoc($result))
//set there status = 0 as offline
$other_user_id = $row['user_id'];
mysqli_query($con, "update tablename set status = 0 where user_id = '$other_user_id'");
//update your own timestamp
mysqli_query($con, "update tablename set timestamp = GETDATE() where user_id='$user_id'");
这将检查用户活动,或者基本上检查该 js 是否正在运行。如果浏览器已关闭,则该用户的 TS 将不会更新,因此 GETDATE() - 时间戳将大于 60。现在将运行 Web 应用程序的其他用户也将运行相同的脚本,检查并更新所有用户状态为每个条件。 当用户关闭他的标签时,他仍会在线至少 1 分钟。
我遇到了类似的问题,在这里PHP auto logout on tab close找到了解决方案。
【讨论】:
以上是关于定时自动注销和浏览器关闭的主要内容,如果未能解决你的问题,请参考以下文章
将数据从mysql导入hive时用户注销和hadoop服务器自动关闭