实测人数小于10w时无性能压力。
概括原理是利用session_id 鉴别与统计用户身份

<?php
session_start();
$sessid = session_id();
$counterfile = "online.log";
$counter = 0;
$newcontent = '';
$findmyself = false; 

//读取计数器部分
$f = fopen($counterfile,'r');

while (!feof($f)) {
    $line = fgets($f);
    $parts = explode("|",trim($line)); //每一行有两个内容,sessionid 和 上线时间戳
    if(count($parts)==2){
        $lsessid = $parts[0];
        $ltime = $parts[1];
        
        if(!is_numeric($ltime)){ //不是时间戳,跳过
            continue;
        }
                
        if((time()-$ltime) < 900){ //15分钟表示在线            
            $counter ++;
            if($sessid == $lsessid){ //自己的记录
              $newcontent .= $lsessid."|".time()."\n"; //更新自己的在线时间
              $findmyself = true;
            }else{ //他人的记录
              $newcontent .= $line; 
            }            
        }else{} //活跃时间超过15分钟,剔除                
    }
}
fclose($f);

if(!$findmyself){//遍历完在线名单没有自己,把自己加进去
    $counter += $newnum;    
    $newcontent .= $sessid."|".time()."\n";
}

//写锁定文件
$f = fopen($counterfile, "w");
$waitcount = 0;
$waitmax = 5;

while(!flock($f, LOCK_EX) || $waitcount > $waitmax){
    sleep(1);
    $waitcount++;
}
if($waitcount <= $waitmax){
    fwrite($f, $newcontent);
    flock($f, LOCK_UN); // 释放锁定    
}else{} //超时,不能获得锁定,放弃写入

fclose($f);

//输出在线人数
die((string) $counter);

标签: php, 在线人数

添加新评论