【发布时间】:2012-03-03 23:56:33
【问题描述】:
我正在尝试创建一个允许用户“登录”和“注销”的小型 Web 应用程序。 我目前遇到的问题是允许客户端向服务器发送持续的“心跳”或消息以通知它仍然处于活动状态。
这更像是一个合乎逻辑的问题。我想要做的是在 php 中有一个 while(1) 循环来检查是否跳过了 n 个心跳。我仍然希望客户端和服务器能够在这个循环进行时进行交互(本质上我希望服务器表现得好像它有一个单独的“check_for_heartbeats”线程。
如何使用 php 实现这一点?我现在正在运行 XAMPP。任何帮助将不胜感激。
编辑:澄清一下,我想要做的是即使在 window.unload 事件不会触发的情况下(例如客户端与互联网断开连接),也能够捕获浏览器关闭事件。在这种情况下,有一个线程来监控心跳似乎是最直观的解决方案,尽管我不确定如何在 php.ini 中实现它。
编辑 2:isLoggedIn() 只是辅助函数,用于检查是否设置了会话布尔变量 ($_SESSION['is_logged_in'))。
最终编辑: 好的,我现在完全理解 cmets 和响应的意思了。因此,解释一下,这是潜在的解决方案: 有 Javascript 代码向服务器发送“心跳”。服务器将添加与这些节拍关联的时间戳。 修改数据库以保存这些时间戳 查询整个“timestamps”表(更可能是具有“timestamp”属性的“users”表),并查看 NOW 和 last timestamps 之间的差异是否大于某个阈值。 “注销”任何超过此阈值的用户。
唯一的问题是如果只有一个用户登录,或者所有用户同时断开连接 - 但在这些情况下,没有其他人会看到用户断开连接。
这是多个响应的组合,但我认为克里斯的响应解决了大部分问题。感谢 chris 和 Alex Lunix 的有益贡献。 :D
这里有一个代码sn-p 更好的解释
服务器端:
function checkBeats()
{
while(isLoggedIn())
{
// it's been > 30 secs since last heartbeat
if((time() - $_SESSION['heartbeat']) > 30)
{
logout();
break;
}
}
}
【问题讨论】:
-
不确定。我认为是的,因为我希望能够捕获诸如用户浏览器崩溃之类的问题(在这种情况下,不会触发 window.onbeforeunload 事件,并且我除了发出 ajax 请求的心跳之外什么都没有)。跨度>
-
我仍然很困惑你需要这个做什么。确保用户仍然登录的目标是什么?为什么你不能在他们每次发出请求时检查一下,并记录最后一次请求时间作为活动的衡量标准?
-
很抱歉给您带来了困惑。是的,我想确保用户仍然登录。客户端的心跳(即来自 javascript 代码的 ajax 请求)允许我确保用户仍然在线,但是我在哪里进行实际的“检查”到确保他们没有离线?现在,我拥有它,以便在任何时候触发 window.unload 事件时,客户端都会发送一条 ajax 消息,说明窗口已关闭。每当触发 onload 事件时,客户端都会告诉服务器窗口已打开。现在,如果客户端的互联网连接失败了——服务器如何发现?
-
php 在没有人访问页面的情况下不会做任何事情,因此为了检查心跳时间并将其设置为已注销,您需要另一种编程语言检查,或者您需要合并一个系统它会检查每个页面加载时的所有心跳时间,并希望人们访问的次数足以刷新数据库。
-
我只是希望数据库保持一致。如果用户失去互联网连接,服务器真的无法发现,因为不会发送心跳。如果我以您建议的方式实现它(这几乎就是我现在的做法),用户将在他/她的互联网断开连接的整个时间内显示“登录”,直到用户决定访问该页面再次。这主要对其他用户来说是个问题,他们可能正在寻找也“登录”的人,并且可能正在与看似已登录但实际上已失去联系的人交谈。
标签: php javascript client heartbeat