Discuz!官方免费开源建站系统

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

剖析在线记录

[复制链接]
evenzhou 发表于 2011-4-29 09:56:47 | 显示全部楼层 |阅读模式
本帖最后由 evenzhou 于 2011-4-29 10:29 编辑

===============discuz! x2=================
广场页面在线显示页面模板为:template\default\forum\discuz.htm
对应的代码:
  1. <div class="bm_h">
  2.                                 <!--{if $detailstatus}-->
  3.                                         <span class="o"><a href="forum.php?showoldetails=no#online" title="{lang spread}"><img src="{IMGDIR}/collapsed_no.gif" alt="{lang spread}" /></a></span>
  4.                                         <h3>
  5.                                                 <strong><a href="home.php?mod=space&do=friend&view=online&type=member">{lang onlinemember}</a></strong>
  6.                                                 <span class="xs1">- <strong>$onlinenum</strong> {lang onlines}
  7.                                                 - <strong>$membercount</strong> {lang index_members}(<strong>$invisiblecount</strong> {lang index_invisibles}),
  8.                                                 <strong>$guestcount</strong> {lang index_guests}
  9.                                                 - {lang index_mostonlines} <strong>$onlineinfo[0]</strong> {lang on} <strong>$onlineinfo[1]</strong>.</span>
  10.                                         </h3>
  11.                                 <!--{else}-->
  12.                                         <span class="o"><a href="forum.php?showoldetails=yes#online" title="{lang spread}"><img src="{IMGDIR}/collapsed_yes.gif" alt="{lang spread}" /></a></span>
  13.                                         <h3>
  14.                                                 <strong><a href="home.php?mod=space&do=friend&view=online&type=member">{lang onlinemember}</a></strong>
  15.                                                 <span class="xs1">- {lang total} <strong>$onlinenum</strong> {lang onlines}
  16.                                                 - {lang index_mostonlines} <strong>$onlineinfo[0]</strong> {lang on} <strong>$onlineinfo[1]</strong>.</span>
  17.                                         </h3>
  18.                                 <!--{/if}-->
  19.                                 </div>
复制代码
$_G['setting']['whosonlinestatus'] 判断是否开启了显示在线,0 不显示 、1 仅在首页显示、 2 仅在分论坛显示、 3 在首页和分论坛显示(设置地方:界面--界面设置--论坛首页--显示在线用户)当后台开启了详细在线情况,将显示用在线列表,和隐身用户的人数。其判断代码为$detailstatus(是否显示在线详细情况)

对应的处理页面:source\module\forum\forum_index.php
获得历史在线人数:
  1. $onlineinfo = explode("\t", $_G['cache']['onlinerecord']);
复制代码
获得当前在线人数:
  1. if(empty($_G['cookie']['onlineusernum'])) {
  2.                         $onlinenum = DB::result_first("SELECT count(*) FROM ".DB::table('common_session'));
  3.                         if($onlinenum > $onlineinfo[0]) {
  4.                                 $onlinerecord = "$onlinenum\t".TIMESTAMP;
  5.                                 DB::query("UPDATE ".DB::table('common_setting')." SET svalue='$onlinerecord' WHERE skey='onlinerecord'");
  6.                                 save_syscache('onlinerecord', $onlinerecord);
  7.                                 $onlineinfo = array($onlinenum, TIMESTAMP);
  8.                         }
  9.                         dsetcookie('onlineusernum', intval($onlinenum), 300);
  10.                 } else {
  11.                         $onlinenum = intval($_G['cookie']['onlineusernum']);
  12.                 }
复制代码
其中 ($onlinenum > $onlineinfo[0])判断当前在线人数(包括在隐身的用户和游客)是否大于过去,如果大于更新最高在线记录
dsetcookie('onlineusernum', intval($onlinenum), 300) 在线人数写入到cookie中有效时间为5分钟
  1. $detailstatus = $showoldetails == 'yes' || (((!isset($_G['cookie']['onlineindex']) && !$_G['setting']['whosonline_contract']) || $_G['cookie']['onlineindex']) && $onlinenum < 500 && !$showoldetails);
复制代码
判断是否显示在线详情  其中 $showoldetails == 'yes' 判断是否显示详情如果为真 则,$detailstatus=true
(!isset($_G['cookie']['onlineindex']) && !$_G['setting']['whosonline_contract']) 没有设置$_G['cookie']['onlineindex'] 并且后台设置了显示在线详情

$_G['uid'] && updatesession()  用户在线切更新session
  1. $query = DB::query("SELECT uid, username, groupid, invisible, lastactivity, fid FROM ".DB::table('common_session')." WHERE uid>'0' LIMIT ".$_G['setting']['maxonlinelist']);
  2.                         while($online = DB::fetch($query)) {
  3.                                 $membercount ++;
  4.                                 if($online['invisible']) {
  5.                                         $invisiblecount++;
  6.                                         continue;
  7.                                 } else {
  8.                                         $online['icon'] = !empty($_G['cache']['onlinelist'][$online['groupid']]) ? $_G['cache']['onlinelist'][$online['groupid']] : $_G['cache']['onlinelist'][0];
  9.                                 }
  10.                                 $online['lastactivity'] = dgmdate($online['lastactivity'], 't');
  11.                                 $whosonline[] = $online;
  12.                         }
复制代码
$membercount 统计会员总数,$invisiblecount 统计隐身的用户。 $online['icon'] = !empty($_G['cache']['onlinelist'][$online['groupid']]) ? $_G['cache']['onlinelist'][$online['groupid']] : $_G['cache']['onlinelist'][0] 得到在线用户的组图标
  1. if(isset($_G['cache']['onlinelist'][7]) && $_G['setting']['maxonlinelist'] > $membercount) {
  2.                                 $query = DB::query("SELECT uid, username, groupid, invisible, lastactivity, fid FROM ".DB::table('common_session')." WHERE uid='0' ORDER BY uid DESC LIMIT ".($_G['setting']['maxonlinelist'] - $membercount));
  3.                                 while($online = DB::fetch($query)) {
  4.                                         $online['icon'] = $_G['cache']['onlinelist'][7];
  5.                                         $online['username'] = $_G['cache']['onlinelist']['guest'];
  6.                                         $online['lastactivity'] = dgmdate($online['lastactivity'], 't');
  7.                                         $whosonline[] = $online;
  8.                                 }
  9.                         }
复制代码
获得最大游客在线显示信息
  1. if($onlinenum > $_G['setting']['maxonlinelist']) {
  2.                                 $membercount = $discuz->session->onlinecount(1);
  3.                                 $invisiblecount = DB::result_first("SELECT COUNT(*) FROM ".DB::table('common_session')." WHERE invisible = '1'");
  4.                         }
复制代码
判断当前用户数是否大于最大在线显示数,如果大于,则只取会员,并统计当前隐身的用户


最近有用户反应在线最高记录总是高低起伏,下面来分析最高记录更新过程:在浏览forum.php是就加载了onlinerecord缓存,在forum_index.php页面判断当前缓存的记录中的最高在线人数是否大于当前在线人数,如果大于则更新缓存common_setting中的onlinerecord,再更新缓存(DB::query("REPLACE INTO ".DB::table('common_syscache')." (cname, ctype, dateline, data) VALUES ('$cachename', '$ctype', '".TIMESTAMP."', '$data')")如果开启了file缓存则删除对应的缓存文件,$allowmem && memory('rm', $cachename))
加载缓存设计到主要函数:loadcache()和cachedata()(函数位置:source\function\function_core.php)
经过分析最有可能导致,最高在线记录数起伏的可能是:数据表common_syscache和common_setting表数据被更改
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|Discuz! 官方站 ( 皖ICP备16010102号 )star

GMT+8, 2024-11-17 08:31 , Processed in 0.025087 second(s), 3 queries , Gzip On, Redis On.

Powered by Discuz! X3.4

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表