如果用户登录,我该如何实时查询?

Dev*_*vWL 14 javascript php ajax session

我正在使用Ajax为我的网站构建一个简单的支持聊天.我想检查我当前正在聊天的用户是否离开了浏览器.

目前,我通过在客户端设置间隔功能来创建具有名称的文件,从而构建该功能: userId.txt

在管理区域中,我创建了一个检查是否userId.txt存在的区间函数.如果存在,则删除它.如果自定义间隔函数没有重新创建文件 - 下次admin函数将发现该文件不存在时,它会将customer标记userId为非活动状态.

抽象表示:

customer -> interval Ajax function -> php [if no file - create a new file]
admin -> interval Ajax function -> php [if file exists - delete the file] -> return state to Ajax function and do something
Run Code Online (Sandbox Code Playgroud)

我想知道是否有更好的方法来实现您能想到的这个功能?

Ped*_*ito 14

我的解决方案是使用jquery readybeforeunload方法来触发一个ajax post请求,该请求将在用户到达和离开时通知.这个解决方案很" ",因为它每个用户只记录两次.

的support.html

<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>

//log user that just arrived - Page loaded
$(document).ready(function() {
         $.ajax({
        type: 'POST',
        url: 'log.php',
        async:false,
        data: {userlog:"userid arrived"}
    });
});

//log user that is about to leave - window/tab will be closed.
$(window).bind('beforeunload', function(){
    $.ajax({
        type: 'POST',
        url: 'log.php',
        async:false,
        data: {userlog:"userid left"}
    });
});
</script>
</head>
<body>

<h2>Your support html code...</h2>

</body>
</html>
Run Code Online (Sandbox Code Playgroud)

log.php

<?php

//code this script in a way that you get notified in real time
//in this case, I just log to a txt file

$userLog = $_POST['userlog'];
file_put_contents("userlog.txt", $userLog."\n", FILE_APPEND );
//userid arrived
//userid left
Run Code Online (Sandbox Code Playgroud)

笔记:

1 - 测试Chrome,FFOpera.我没有mac,所以我无法测试它,Safari但它也应该工作.
2 - 我尝试过卸载方法,但它没有那么可靠beforeunload.
3 - 设置asyncfalseon ajax请求表示您调用的语句必须在下一个语句之前完成,这可确保您在窗口/选项卡关闭之前得到通知.


Dev*_*von 5

@Gonzalon提出了一个很好的观点,但使用普通的数据库表或文件系统不断更新用户移动对于大多数硬盘来说都是穷举.这是在PHP中使用共享内存函数的一个很好的理由.


Jen*_*och 5

您必须区分原始问题"我如何实时登记,如果用户已登录?" 并且"如果用户仍然在另一边(在我的聊天中),我怎么能确定?".

对于"登录系统",我建议使用PHP会话.

对于"仍然存在用户"的问题,我建议更新名为的活动会话的一个字段LAST_ACTIVITY.有必要将与客户端的最后一次联系的时间戳写入存储(数据库)并测试是否早于X秒.

我建议会话,因为你没有在你的问题中提到它们,看起来你在每个Ajax请求上手动创建userID.txt文件,对吧?这是不需要的,除非工作cookie和无会话是一个开发要求.

现在,对于PHP会话,我只需将会话处理程序(后端)更改为适合您的任何比例以及使请求信息变得容易的原因.默认情况下,PHP使用会话临时文件夹来创建会话文件,但您可以更改它,以便底层会话处理程序成为mariadb数据库或memcache或rediska.

当用户会话存储到数据库中时,您可以查询它们:"现在有多少用户登录?","谁在哪里?".

答案为"如果用户登录,我如何实时查看?" 是,在创建用户会话并成功验证用户时.


对于实时聊天应用程序,有很多技术,从"php comet","html5 eventsource"+"websockets"/"long polling"到"message queues",如RabbitMq/ActiveMq,具有发布/订阅特定功能通道.

如果这是一个简单或受限制的环境,也许是VPS,那么您仍然可以坚持使用间隔Ajax请求的解决方案.然后,每个请求都可以$_SESSION['LAST_ACTIVITY']使用服务器端时间戳进行更新.参考:https://stackoverflow.com/a/1270960/1163786

对此想法的修改是在鼠标移动停止时停止执行Ajax请求.如果用户未在页面上移动鼠标(例如10分钟),则会停止更新LAST_ACTIVITY时间戳.这将解决显示闲置用户在线的问题.

另一种修改是通过使用小的GET或HEADER请求来减少服务器的"仍然在这里"请求的大小.一个简短的HEADER"ping"通常就足够了,而不是通过POST发送长消息或JSON.

您可以在此处找到完整的"如何使用PHP创建Ajax Web聊天,jQuery".他们使用15秒的超时时间进行聊天.