简体   繁体   English

如何在具有 php 和 mysql 驱动数据库的网站中查看用户是否在线?

[英]How to see if a user is online in a website with php and mysql driven databases?

I'm building a community website.我正在建立一个社区网站。 Users will login and logout as usually.用户将像往常一样登录和注销。

I use the attribute status online/offline to set the user's status.我使用属性 status online/offline 来设置用户的状态。 But what if a user just clicks the X button or disconnects otherwise without logging out?但是,如果用户只是单击 X 按钮或以其他方式断开连接而不注销,该怎么办?

Lately my computer crashed, when I opened the site with my laptop I could not login because I don't allow login in two places.最近我的电脑崩溃了,当我用笔记本电脑打开网站时,我无法登录,因为我不允许在两个地方登录。 I go to PHPMyAdmin and I see my status still online.我去 PHPMyAdmin,我看到我的状态仍然在线。 Is there any fix for this.有没有解决办法。

I tried the last_time activitiy thing but that doesn't work in case of a computer crash!我尝试了 last_time 活动,但在计算机崩溃的情况下不起作用! And there was nothing neither interactivity or refresh to update the table.并且没有任何交互性或刷新来更新表。

You don't need the online/offline flag, you just need to save the last activitity time.您不需要在线/离线标志,您只需要保存最后一次活动的时间。 When displaying the user status, if last activity time is less than now+15 minutes then user is online, offline otherwise.显示用户状态时,如果上次活动时间小于现在+15分钟,则用户在线,否则离线。

Because of the nature of the web, you can't know when a user disconnects, yanks the cable or shuts down his computer without politely telling you.由于网络的性质,如果没有礼貌地告诉您,您无法知道用户何时断开连接、猛拉电缆或关闭他的计算机

You could have a script (AJAX) check every X minutes to see if the browser still responds, and if not, toggle offline - but that would consume extra resources.您可以让脚本 (AJAX) 每 X 分钟检查一次以查看浏览器是否仍然响应,如果没有,则切换到离线状态 - 但这会消耗额外的资源。 This is how for example an IRCd works: they PING you, you PONG back.例如,这就是 IRCd 的工作方式:他们 PING 你,你 PONG 回来。 If you don't pong back, you timeout and get disconnected from the server.如果您不回击,则会超时并与服务器断开连接。

HTTP is stateless, there is no other built-in solution. HTTP 是无状态的,没有其他内置解决方案。 Maybe HTML5 and sockets, but that would be the same principle as just plain AJAX.也许是 HTML5 和套接字,但这与普通 AJAX 的原理相同。

CREATE TABLE `user_online` (
`session` char(100) NOT NULL default '',
`time` int(11) NOT NULL default '0'
) TYPE=MyISAM;

<?php

session_start();
$session=session_id();
$time=time();
$time_check=$time-600; //SET TIME 10 Minute

$host="localhost"; // Host name
$username=""; // Mysql username
$password=""; // Mysql password
$db_name="test"; // Database name
$tbl_name="user_online"; // Table name

// Connect to server and select databse
mysql_connect("$host", "$username", "$password")or die("cannot connect to server");
mysql_select_db("$db_name")or die("cannot select DB");

$sql="SELECT * FROM $tbl_name WHERE session='$session'";
$result=mysql_query($sql);

$count=mysql_num_rows($result);

if($count=="0"){

$sql1="INSERT INTO $tbl_name(session, time)VALUES('$session', '$time')";
$result1=mysql_query($sql1);
}

else {
"$sql2=UPDATE $tbl_name SET time='$time' WHERE session = '$session'";
$result2=mysql_query($sql2);
}

$sql3="SELECT * FROM $tbl_name";
$result3=mysql_query($sql3);

$count_user_online=mysql_num_rows($result3);

echo "User online : $count_user_online ";

// if over 10 minute, delete session
$sql4="DELETE FROM $tbl_name WHERE time<$time_check";
$result4=mysql_query($sql4);

// Open multiple browser page for result


// Close connection

mysql_close();
?>

You can use this method 1. check user status if it is online check last activity if it is more than 10 min set status to offline if it is less than 10 min show till user online if it is off line show user offline您可以使用此方法 1. 检查用户状态是否在线 检查上次活动 如果超过 10 分钟 设置状态为离线 如果少于 10 分钟显示直到用户在线 如果离线显示用户离线

  1. When user using this site update last activity in every "x" min with ajax当用户使用此站点时,每“x”分钟使用 ajax 更新一次活动
  2. When user click on logout set status to off line.当用户单击注销时,将状态设置为离线。 This could be your database structure.这可能是您的数据库结构。

在此处输入图片说明

You can run a function on each page request that updates a row in your database with your user's ID and a calculated timestamp for the future (eg time()+(60*5); - five minutes).您可以在每个页面请求上运行一个函数,用您的用户 ID 和计算的未来时间戳更新数据库中的一行(例如time()+(60*5); - 五分钟)。 Then whenever another user attempts to check if the first user is online, you can check it against the database using a 'pulse' check:然后,每当另一个用户尝试检查第一个用户是否在线时,您可以使用“脉冲”检查对数据库进行检查:

$time = time();
$query = mysql_query("SELECT user_id, timestamp FROM online_users WHERE user_id = '$user_id' AND timestamp > '$time'");

If this query returns more than 0 rows, the user is considered online.如果此查询返回多于 0 行,则认为用户在线。

Farfetched solution.牵强的解决方案。

Use a node.js server with socket.io.使用带有 socket.io 的 node.js 服务器。 Have the client connect to the server via the socket.io client side.让客户端通过 socket.io 客户端连接到服务器。 The server is responsible for emitting events to the clients and expecting a response.服务器负责向客户端发出事件并等待响应。 On disconnect or late response mark the user offline.在断开连接或延迟响应时,将用户标记为离线。

It will work and probably will be working even on cable disconnects/browser closing but is it worth the effort?它会工作,甚至可能会在电缆断开/浏览器关闭时工作,但值得付出努力吗?

wait man, i think i have the right reply because i did faced the same problem !等等,我想我有正确的答复,因为我确实遇到了同样的问题! try to use the mouse event [click,movemouse ..] but with a delay to not creat a crash in the navigator, you will use setInterval on a xx sec or minutes after you save the event reply to your db in the activity column but with unix time in order to differentiate it later to the now time .. its useful really, i used it to log members acitvity to know what they really do in real time and get the online/offline users too.尝试使用鼠标事件 [click,movemouse ..] 但延迟不会在导航器中造成崩溃,您将在 xx 秒或分钟后使用 setInterval 在活动列中将事件回复保存到您的数据库,但是使用 unix time 以便将其区分为现在的时间..它真的很有用,我用它来记录会员的活动以实时了解他们真正在做什么,并获得在线/离线用户。 here is the used js functions:这是使用的js函数:

var body = document.getElementById('body');
var url = './member-activity.php?loggedUser=<?=$memb_id?>&curl=<?=($_SERVER['QUERY_STRING'])?>';
if(document.addEventListener) {
  document.addEventListener("click", _EventLogging, false);
    document.addEventListener("mousemove", _EventLogging, false);
}else{
  document.attachEvent("onclick", _EventLogging);
}
function _EventLogging(){
//call it after a delay of 
setTimeout(AjaxUrl(url), 2000); //delay of 2 sec after every move of cursor
}
//AjaxUrl is a js function that calls a php file to perform the activity logging via AJAX
</script>
<div id="id"></div>

the div above is to notify you about errors in code, u remove it when its ok!上面的 div 是为了通知您代码中的错误,您可以在正常时将其删除! i hope that my answer was right for ur case //dr.alpha@hotmail.co.uk我希望我的回答适合你的案例 //dr.alpha@hotmail.co.uk

Well the real answer for ur question "How will i update the table without user interaction ?"你的问题“我将如何在没有用户交互的情况下更新表格?”的真正答案。

is MySql event scheduler , you schedule a an event (query) to be executed at whenever you wish even if the user is OFFLINE , read about it here ( http://dev.mysql.com/doc/refman/5.1/en/events-overview.html )是 MySql 事件调度程序,即使用户处于离线状态,您也可以安排一个事件(查询)随时执行,请在此处阅读( http://dev.mysql.com/doc/refman/5.1/en/事件概述.html )

您可以通过在数据库中记录用户的最后一个活动(在每个页面加载、刷新、执行的操作上)然后检查session.gc_maxlifetime (以秒为单位)并使用用户的最后一个活动计算用户的会话是否已过期来实现这一点.

实际上唯一准确的方法是使用websocket ,它会与用户进行实时通信,试试Ratchet

You're on the right path: save user's last activity's UNIX time in the database, and, when someone accesses the site, set the offline status for users that were not active for 15 minutes (or less).您走在正确的道路上:将用户上次活动的 UNIX 时间保存在数据库中,并且当有人访问该站点时,为 15 分钟(或更短时间)未处于活动状态的用户设置脱机状态。 If the user is logged in and his status is set to offline in the database, force him to logout (destroying the session).如果用户已登录并且他的状态在数据库中设置为离线,则强制他注销(破坏会话)。

However, the real question is: is it worth it?然而,真正的问题是:值得吗? I haven't seen any similar authentication system yet.我还没有看到任何类似的身份验证系统。

I would use a combination of timing out sessions that have not had recent activity and expiring old sessions when a successful log in attempt is made.当尝试成功登录时,我将结合使用最近没有活动的超时会话和过期的旧会话。

As Konerak mentioned HTTP is stateless and there is no built-in way of telling if someone has left your site .正如 Konerak 提到的 HTTP 是无状态的,并且没有内置的方式来判断是否有人离开了您的站点 You could figure it out with some sort of JavaScript based polling technique, but this would cause a lot of overhead that just isn't necessary in most situations.您可以使用某种基于 JavaScript 的轮询技术来解决这个问题,但这会导致大量开销,而这在大多数情况下是不必要的。

Instead you should keep track of the last time there was any activity from a user and store that time in your database or better yet something like memcache .相反,您应该跟踪上次用户进行任何活动的时间并将该时间存储在您的数据库中,或者更好的方式是memcache If a users last activity time is longer than a timeout period you decide on assume they are no longer on the site.如果用户上次活动时间长于您决定的超时期限,则假设他们不再在网站上。

The second part would be instead of denying a log in when someone tries to log in after leaving the site without logging out, let them log in and invalidate any old sessions associated with their account.第二部分是当有人在离开站点后未注销而尝试登录时拒绝登录,而是让他们登录并使与其帐户关联的任何旧会话无效

As per your scenario, you can use the below logic to check the status of the user:根据您的情况,您可以使用以下逻辑来检查用户的状态:

Instead of checking whether the user is online or offline only depednding upon the value of the table column, use the session variable as well.与其仅根据表列的值检查用户是在线还是离线,不如使用 session 变量。 for example consider below code:例如考虑下面的代码:

 <?php

  $stauts_from_table_column;

  if($stauts_from_table_column==1 && isset($_SESSION['userid']))
  {
   $user_logged_in = true;
  }
  else
  {
   $user_logged_in = false;
  }     

?>

You can enhance it further, but you get my point i hope.你可以进一步增强它,但我希望你明白我的意思。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM