Javascript 如果用户已登录,如何实时签入?

Javascript 如果用户已登录,如何实时签入?,javascript,php,ajax,session,Javascript,Php,Ajax,Session,我正在使用Ajax为我的网站构建一个简单的支持聊天。我想检查当前与我聊天的用户是否离开了浏览器 目前,我已经通过在客户端设置interval函数来构建该功能,该函数创建名为:userId.txt的文件 在管理区域中,我创建了一个interval函数,用于检查是否存在userId.txt。如果它存在,它将删除它。如果文件不是由自定义间隔函数重新创建的-下次管理函数将发现文件不在那里时,它将使用此用户ID将客户标记为非活动 摘要表述: customer -> interval Ajax fun

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

目前,我已经通过在客户端设置interval函数来构建该功能,该函数创建名为:
userId.txt的文件

在管理区域中,我创建了一个interval函数,用于检查是否存在
userId.txt
。如果它存在,它将删除它。如果文件不是由自定义间隔函数重新创建的-下次管理函数将发现文件不在那里时,它将使用此
用户ID
将客户标记为非活动

摘要表述:

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

我想知道是否有更好的方法来实现这一功能,你能想到吗?

@Gonzalon提出了一个很好的观点,但是使用一个普通的DB表或文件系统来不断更新用户移动对大多数硬盘来说是彻底的。这是在PHP中使用函数的一个很好的理由

您可以这样做,但这样做速度慢、效率低,而且可能非常不安全。使用数据库将是一个显著的改进,但即使是这样也不会具有特别的可伸缩性,这取决于您希望它的“实时性”程度以及您希望它能够同时处理的会话数量

对于需要频繁运行的任何操作(例如:“用户是否在线”检查、存储短期会话更新以及在短时间内检查会话更新),最好使用诸如Redis之类的NoSQL解决方案


然后,您将使用数据库执行更长期的任务,如存储用户信息和定期保存活动对话(例如,可能每分钟一次)。

为什么是Ajax而不是WebSocket?当然,websocket会给你一个更快的聊天系统,不需要生成和检查文本文件,不会涉及数据库查找,您可以立即判断连接是否断开。

我的解决方案是使用
jquery
和方法触发
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>

//刚刚到达的日志用户-已加载页面
$(文档).ready(函数(){
$.ajax({
键入:“POST”,
url:'log.php',
async:false,
数据:{userlog:“userid已到达”}
});
});
//即将离开的日志用户-窗口/选项卡将关闭。
$(窗口).bind('beforeunload',function(){
$.ajax({
键入:“POST”,
url:'log.php',
async:false,
数据:{userlog:“userid left”}
});
});
您的支持html代码。。。
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

我建议为此使用内置HTML5会话存储。所有现代浏览器都支持这一点,因此我们不会面临同样的问题


这将帮助我们高效、快速地识别用户是否在线。每当用户移动鼠标或按键时,用日期和时间更新会话存储。定期检查它,看看它是空的还是空的,并判断用户是否离开了网站。

您必须区分最初的问题“如果用户登录,我如何实时签入?”和“如果用户仍在另一端(在我的聊天中),我如何确保?”

对于“登录系统”,我建议使用PHP会话

对于“用户还在吗”问题,我建议更新活动会话中名为
LAST\u ACTIVITY
的一个字段。有必要将最后一次与客户机联系的时间戳写入存储(数据库),并测试该时间戳是否早于X秒

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

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

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

“如果用户已登录,如何实时签入?”的答案是,当用户会话创建且用户已成功通过身份验证时


对于实时聊天应用程序,有很多技术,从“php comet”、“html5 eventsource”+“websockets”/“长轮询”到“消息队列”,比如发布/订阅特定通道的RabbitMq/ActiveMq

如果这是一个简单或受限的环境,可能是一个VPS,那么您仍然可以坚持使用intervalic Ajax请求的解决方案。然后,每个请求可能会使用服务器端时间戳更新
$\u会话['LAST\u ACTIVITY']
。参考:

对这个想法的一个修改是,当鼠标移动停止时,停止执行Ajax请求。如果用户在页面上10分钟内不移动鼠标,您将停止更新最后一个_活动时间戳。这将解决显示空闲用户在线的问题

另一个修改是通过使用小GET或标头请求来减小对服务器的“iam仍然在这里”请求的大小。短标题“ping”通常就足够了,而不是通过POST发送长消息或JSON

您可以在这里找到完整的“如何使用PHP、jQuery创建Ajax Web聊天”。他们使用15秒的超时时间进行聊天

  • 第一部分

  • 第二部分


您可以不创建和删除文件
var server = require('http').Server();
var io = require('socket.io')(server);
var Redis = require('ioredis');
var redis = new Redis();

var authenticatedUsers = [];

// Subscribe to the authenticatedUsers channel in Redis
redis.subscribe('authenticatedUsers');

// Logic for what to do when a message is received from Redis
redis.on('message', function(channel, message) {
  authenticatedUsers.push(message);
  io.emit('userAuthenticated', message);
});

// What happens when a client connects
io.on('connection', function(socket) {
  console.log('connection', socket.id);

  socket.on('disconnect', function(a) {
    console.log('user disconnected', a);
  });
});

server.listen(3000);