什么是确定用户是否在线的最简单方法? (PHP / MYSQL)

时间:2009-06-27 01:24:57

标签: php javascript mysql offline

我有没有办法让会话能够知道用户是否在线?

即:使用登录,我设置$ _SESSION变量,用户超时cookie垃圾收集器更新数据库以将其状态更新为脱机。

EDIT:我想要一个不涉及时间或日期的解决方案。我想要一些东西可以骑在会话或类似的东西上。猜猜某人是否在线并不足以满足我的需求。

10 个答案:

答案 0 :(得分:86)

不要费心去弄清楚时区之间的差异。这不是必要的。

每当用户访问页面时,更新其用户表last-updated-time记录中的字段。然后对最近5分钟内具有最后更新时间的所有用户进行查询。除此之外的任何东西,它们都被视为“离线”。

如果您使用服务器时间,通过MySQL中的NOW()函数,您将侧面计算时区之间的差异。

这是跟踪当前在线用户数量的标准方式(含义,在过去几分钟内有效)。

不断更新

如果你想知道他们仍然活跃,即使他们没有从一个页面跳到另一个页面,请每60秒左右包含一些javascript来ping你的服务器,让你知道他们还活着。它的工作方式与我原来的建议相同,但它会更新您的记录,而不要求他们至少每五分钟疯狂浏览一次您的网站。

var stillAlive = setInterval(function () {
    /* XHR back to server
       Example uses jQuery */
    $.get("stillAlive.php");
}, 60000);

答案 1 :(得分:5)

根据定义,您所要求的(澄清之后)是不可能的。 HTTP是一种无连接协议,因此只要用户点击页面并且所有内容从服务器返回到用户的浏览器,两者之间就没有连接。有人在您网站上“在线”不到一秒钟。

可以做的一件事就是让您的网页上的JavaScript定期向您的服务器发送AJAX请求,其中包括识别信息,以及当用户离开页面时的不同AJAX请求,使用 window.onbeforeunload

答案 2 :(得分:4)

我的方式可能不是最好的方法,但由于我的网站和用户群都在mysql DB中,当用户登录我的网站时,

  1. 我更新用户表来说出来 在线
  2. 将它们插入在线表格
  3. 然后我设置了一个会话 当前时间
  4. 然后在每个页面加载我检查在线时间会话,如果它存在,我检查看它有多久,如果它不到5分钟,我什么都不做,如果它比5分钟更早,然后我用当前时间再次更新会话时间,并用时间

    更新在线用户表

    然后我有一个每10-15分钟运行一次的cron作业,删除在线表中的任何用途,如果在线时间在X分钟内更新,则将用户表标记为离线

答案 3 :(得分:2)

听起来你的“在线人”比较逻辑没有考虑到时区。如果您以这种方式处理时区,我强烈建议您将所有时间存储在GMT中,并在显示之前将其转换为当地时间。这将使任何比较操作变得非常简单。

关于时区here,有一个很好的SO帖子。

答案 4 :(得分:2)

我建议的一件事是将这种信息存储在内存中,例如memcached或mysql heap或redis。因为否则数据库会受到很大影响。

答案 5 :(得分:1)

将时区存储在表格中,并在计算中使用它来查找用户本地时间与查看页面的用户的本地时间相比较。

修改

更好的是,将所有时间都存储为服务器时间,并将所有计算仅基于服务器时间。

答案 6 :(得分:0)

取决于您的情况,您可能最好创建一个单独的表“which-online”,其中包含列:“ip”和“last-updated-time”,并在每次用户加载时查询/更新此表一页。

页面加载查询可能包括

  1. 根据ip更新/插入当前用户的“who-online”表。
  2. 删除“过期”行(也可以使用cronjob定期完成)。
  3. 统计“有效”用户。
  4. 使用此技术的好处

    1. 如果用户未登录,他/她仍在被计算/跟踪。
    2. 取决于您拥有的用户数量,查询此表可能会更快。
    3. 注意:如果您使用此功能,您应该考虑到任何网页浏览都会在您的表格中创建一行,因此根据useragent您可以忽略机器人或只计算流行的(Firefox,IE,Safari,Opera等) )。

答案 7 :(得分:0)

我为此实现的解决方案是,在经过身份验证的用户的每个页面加载时,设置/重置memcache var,例如“user_ {userid} isonline”=>为真,并在5分钟后到期。然后在我访问用户的信息时检查var是否在缓存中。根据您的用户群的大小,如果您想在线获得每个人的列表,您可以使用memcache getmulti调用,为所有用户提供一组“user {userid} _isonline”键。 / p>

当然,这实际上取决于用户更改网站页面的频率...为了更准确地在线表示用户,您可以在页面上以较小的间隔实现ajax xmlhttprequest调用(大约30秒左右)重置memcache var,并让memcache var在更短的时间内过期(1分钟以解决可能的浏览器问题)。这并不完全准确,但由于http没有与服务器的持久连接,因此您可以做的事情非常有限。

如果您需要最多在线的第二个表示,您可以在页面中加载一个连接到jabber服务器的Flash应用程序,然后检查该特定用户是否已登录服务器。 / p>

答案 8 :(得分:0)

你也可以使用onunload标签......在身上 更多信息(https://www.w3schools.com/jsref/event_onunload.asp

这样您就不必等待4-5分钟让用户离线。

但是,如果用户的浏览器崩溃,你仍然应该使用ajax更新方法......

答案 9 :(得分:0)

这里介绍了如何在几分钟内从数据库中获取两个日期之间的差异,然后检查差异并设置在线/离线状态。

$query = 'SELECT * FROM Users';
$result = mysqli_query($mysqli, $query);

foreach($result as $user){
    // date from the database
    $dbLastActivity = date("d-m-Y h:i:s a", strtotime($user['lastOnline']));
    // date now
    $now = date("d-m-Y h:i:s a", $date);

    // calculate the difference
    $difference = strtotime($now) - strtotime($dbLastActivity);
    $difference_in_minutes = $difference / 60;

    // check if difference is greater than five minutes
    if($difference_in_minutes < 5){
        // set online status
        $updateStatus = 'UPDATE Users SET Status="online" WHERE lastOnline="'.$user['lastOnline'].'"';
    } else {
        // set offline status
        $updateStatus = 'UPDATE Users SET Status="offline" WHERE lastOnline="'.$user['lastOnline'].'"';
    }

    // check if mysqli query was successful
    if (!$mysqli->query($updateStatus)){
        printf("Error Message %s\n", $mysqli->error);
    }
}