定时自动注销和关闭浏览器


timed auto logout and browser close

为了学习,我创建了一个非常简单的多用户游戏。

当用户登录时,每个其他用户都会获得当前登录的所有用户的更新。

当用户登录时,它只需在SQL数据库中将该用户的值设置为1。当他们注销时,值应该为0。

我正在使用$(window).unload(function(){});试图捕捉tab/浏览器关闭,但它只是在某种程度上起作用。

两个问题:

  1. 有没有更好的方法来捕捉浏览器或选项卡的关闭?

  2. 如果它错过了关闭标签,或者他们的机器崩溃,或者互联网连接中断,或者用户只是离开了机器,我想继续并自动注销他们。

我使用的是带有PHP后端的HTML/Jquery前端。我能做些什么来完成第二个问题?我想我需要用PHP来做。。我们的工作假设是浏览器可能不再存在,因此不处理jquery的内容。PHP能在一个连续计时器上做些什么来检查用户是否还在。。。而不是简单地让用户每10秒点击一个按钮?

编辑:这里有一个潜在的解决方案:如何在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后端文件主要设置为捕获后变量并运行代码,然后将其交回jquery。由于这段代码是用来注销不活动的浏览器/用户的,所以我不能依赖jquery向PHP发送请求,也不能刷新PHP。我需要做一些cron工作或一些奇怪的事情来让PHP检查所有在过去X秒内没有更新的用户吗?

救命!

不知道第一个问题,但关于第二个问题的建议如何:

当用户处于"活动"状态时,他们是否会定期引发页面请求?如果是这样的话,您可以有一个系统,登录的用户会定期登录到您的SQL数据库中,并带有时间戳。然后让另一个脚本查找所有时间戳超过指定时间段(如10秒)的用户,并将其设置为"0"。

我可以建议一些代码,但也许这不是你想要的——让我知道。

编辑:好的,你编辑的链接似乎用了一个与我刚才建议的类似的系统来回答。如果您使用AJAX,您可以在后台定期调用php脚本来设置和检查SQL表中的时间戳。

您可以实现基于$_SESSION的解决方案,就像Gumbo回答这个问题一样。然后您可以对其进行调整,以满足您的数据库需求。

如果使用html5套接字连接作为连接到服务器的方式,则套接字服务器脚本将知道订阅者何时断开连接。这还允许您实时将数据推送到所有客户端,而无需长时间轮询。唯一的问题是我现在不知道html5套接字的支持是什么。我使用Flash做了类似的事情,它也支持套接字连接。

不要只在用户登录时设置标志,而是记录一个可以用来确定登录时间的时间戳。此外,您还可以让您的客户端使用AJAX调用home一些PHP脚本,将上次用户活动的时间戳保存在数据库中。

然后,您可以使用服务器中的cron作业定期执行会话清理器脚本。脚本将查询数据库以检测过时的会话并注销(将登录标志设置为0)。如果服务器安装了PHP CLI(命令行界面),则可以用PHP编写脚本。

只捕捉关闭窗口后返回网站的用户的一种可能方法是使用用户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();."'"");
    }

然后,我们可以在每次根据time();加载页面时检查这一点,如果用户通过"X"按钮关闭窗口,则会话结束。现在我们必须开始一个新的会话,但这就是为什么我们节省了数据库中的时间。

$_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;
}

我假设,用户在注销时显示为联机和脱机。销毁会话或cookie需要客户端浏览器处于工作模式。

解决方案

我还假设维护了一个时间戳列。设置一个间隔以检查当前TS和上次时间戳之间的时间间隔。还根据您的id将您自己的TS更新为当前TS。

setInterval(function(){ 
    $.ajax({
        url: "/backend.php?userid=id",
        success: function(resoponse){
            console.log(response);
        }
    });
}, 10000);

backend.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在选项卡关闭时自动注销的解决方案。