PHP判断用户在线的另类方法

我想在后台加个功能来显示每个用户是否在线还是离线。

在网上找了很多资料,常见的无非以下几种

方法一、利用登录时间进行判断

    实现方法:用户表加个字段例如update_time来记录用户最后操作的时间,我们设置过期时间为5分钟,前台需要在用户操作界面的时候更新update_time字段。

    缺点:如果用户登录之后超过五分钟没有操作界面,一直挂在哪里。这种情况下用户也是在线的,后台就会判断不准确。而且会有五分钟的延迟判断

方法二、利用登录时间+ajax进行判断

    实现方法:在方法一的基础上加上ajax,每隔一段时间提交一次,即使用户不操作界面ajax也会自动提交数据。

    缺点:频繁操作数据库,如果在线人数太多的话,对数据库压力太大(方法一也是)。还有一个缺点就是有延迟,如果ajax更新完update_time就关闭浏览器了,后台也会显示在线,不能实时统计,有一段时间的延迟。


方法三、利用登录时间+sessionID进行判断

    实现方法:在方法一的基础上加上一个sessionID字段,用户登录的时候设置登录时间和sessionID,然后设置session过期时间(假如设置五分钟)。用户操作界面的时候更新update_time字段。如果用户没在五分钟操作界面,就会因为session过期被迫下线。

    缺点:同上,有五分钟的延迟,需要频繁操作数据库

以上这三种方法是网上见到最多的,其实他们实现的方法都大同小异,最严重的缺点就是有延迟,和频繁操作数据库,如果想降低操作数据库的频率,就要加大过期时间间隔,这样判断延迟差就会更大。


如果想要无延迟的实时监控在线用户还有一种方法就是socket协议。前台用websocket,php网上也有很多的封装好的socket协议例如Swoole和Workerman。


再来说下我的实现思路:

    我也是利用sessionID,但是可以做到无延迟判断用户是否在线。

    我们首先要知道session信息是真实且已文件的方式储存在服务上的,通过session_save_path可以获取储存路径QQ截图20190418151048.png

储存格式如上图 sess_加sessionID。

用户访问网站,会在该目录下生成一个文件,并且在内存开辟一个会话进行占用没,这个时候用unlink是无法删除的(这是实现重点!!!记住),当用户关闭浏览器的时候服务器是不会自动删除这个过期文件的,而且在下次打开浏览器访问的时候会再次分配一个随机的sessionID然后在该目录下生成一个新的session文件。也就是说,用户关闭浏览器(退出的时候)session文件不会自动删除,但是会解除对session的占用,这个时候unlink命令是可以删除的。

说道这里可能你已经明白怎么实现判断用户在线的功能了,就是用unlink删除文件的形式。后台先对该目录下的所有session文件执行一遍删除,无效的session会被删除掉,有效的就会保留下来,然后再从数据库保存的sessionID和现存的session文件进行对比,如果存在该文件就说明这个用户是在线的,不存在就是离线。


$path=session_save_path();
        $files=scandir($path);
        for($i=0;$i<count($files);$i++){
            if($files[$i]=='.' || $files[$i]=='..'){
                continue;
            }
            //加上@ 防止删除正在使用的session文件时报错
            @unlink($path."/".$files[$i]);
        }



    

  • blogger

发表评论

    微笑 大笑 拽 大哭 奸笑 流汗 喷血 生气 囧 不爽 晕 示爱 卖萌 吃惊 迷离 爱你 吓死了 呵呵