设为首页收藏本站--- 驰名中外的国际土木工程技术交流平台!

东南西北人

 找回密码
 注册

QQ登录

只需一步,快速开始

总共8814条微博

动态微博

本站帖子精华之精华汇总 Best of the Best英语口语、听力、翻译、考试学习经验交流与探讨1000多土木工程类行业软件、计算表格和计算工具免费下载东南西北人网站QQ精英群 QQ189615688
中国土木工程师手册(上中下)东南西北人英文资料走马观花500多专业手册、工程手册100多个专业词典大汇总
如何获取积分和金币?精彩施工和土木工程技术视频东南西北人英汉对照资料汇总各版块精彩讨论贴汇总!
查看: 548|回复: 3

在线时间更新机理分析(附在线时间和在线用户错误的原因和解决方法)

[复制链接]
鲜花(132) 鸡蛋(3)
东南西北人 发表于 2011-8-19 00:19:12 | 显示全部楼层 |阅读模式
最近在论坛上出现了许多站点的用户在线时间,或者在线用户的列表出现错误数据。针对以上现象,我简单介绍下论坛更新在线时间和在线用户的机理。(以下针对X2版本,其他各个版本的原理基本相同)。


所有的操作都在模板文件footer.htm中的一个不起眼的一条语句<!--{eval updatesession();}-->
<!--{eval updatesession();}-->调用的是function_core.php中的updatesession函数。

  • function updatesession($force = false) {
  •     global $_G;
  •     static $updated = false;
  •     if(!$updated) {
  •         if($_G['uid']) {
  •             if($_G['cookie']['ulastactivity']) {
  •                 $ulastactivity = authcode($_G['cookie']['ulastactivity'], 'DECODE');
  •             } else {
  •                 $ulastactivity = getuserprofile('lastactivity');
  •                 dsetcookie('ulastactivity', authcode($ulastactivity, 'ENCODE'), 31536000);
  •             }
  •         }
  •         $discuz = & discuz_core::instance();
  •         $oltimespan = $_G['setting']['oltimespan'];
  •         $lastolupdate = $discuz->session->var['lastolupdate'];

复制代码
$oltimespan = $_G['setting']['oltimespan'];对应的值是后台全局--站点功能--其他--用户在线时间更新时长(分钟)的值。
  •          if($_G['uid'] && $oltimespan && TIMESTAMP - ($lastolupdate ? $lastolupdate : $ulastactivity) > $oltimespan * 60) {
  •             DB::query("UPDATE ".DB::table('common_onlinetime')."
  •                 SET total=total+'$oltimespan', thismonth=thismonth+'$oltimespan', lastupdate='" . TIMESTAMP . "'
  •                 WHERE uid='{$_G['uid']}'");
  •             if(!DB::affected_rows()) {
  •                 DB::insert('common_onlinetime', array(
  •                     'uid' => $_G['uid'],
  •                     'thismonth' => $oltimespan,
  •                     'total' => $oltimespan,
  •                     'lastupdate' => TIMESTAMP,
  •                 ));
  •             }
  •             $discuz->session->set('lastolupdate', TIMESTAMP);
  •         }

复制代码
如果是会员登录论坛,判断最近更新时间与当前时间的差大于用户在线时间更新时长时,会更新pre_common_onlinetime表(记录会员在线时间)里对应用户的对应字段的值,若没有对应用户,则添加一条记录。
  •        foreach($discuz->session->var as $k => $v) {
  •             if(isset($_G['member'][$k]) && $k != 'lastactivity') {
  •                 $discuz->session->set($k, $_G['member'][$k]);
  •             }
  •         }
  •         foreach($_G['action'] as $k => $v) {
  •             $discuz->session->set($k, $v);
  •         }
  •         $discuz->session->update();
  •         $updated = true;

复制代码
然后程序开始更新session(针对所有用户,包括未登录的游客),将session数据存到pre_common_session表里。
  •        if($_G['uid'] && TIMESTAMP - $ulastactivity > 21600) {
  •             if($oltimespan && TIMESTAMP - $ulastactivity > 43200) {
  •                 $total = DB::result_first("SELECT total FROM ".DB::table('common_onlinetime')." WHERE uid='$_G[uid]'");
  •                 DB::update('common_member_count', array('oltime' => round(intval($total) / 60)), "uid='$_G[uid]'", 1);
  •             }
  •             dsetcookie('ulastactivity', authcode(TIMESTAMP, 'ENCODE'), 31536000);
  •             DB::update('common_member_status', array('lastip' => $_G['clientip'], 'lastactivity' => TIMESTAMP, 'lastvisit' => TIMESTAMP), "uid='$_G[uid]'", 1);
  •         }
  •     }
  •     return $updated;
  • }

复制代码
最后根据用户最近的更新的时间,将计算出的用户在线时间,更新到pre_common_member_count表(统计用户记录信息表)里,我们看到的在线时间就是从此表里读取出来的,并且记录当前时间为用户最近活跃的时间。(注意:pre_common_member_count表中的在线时间是每12个小时更新一次)

以上有两个关键点:
在线时间的统计是由该函数执行和保存的,在线会员显示是直接读取的pre_common_session表中的数据

问题解决方法:
因此,出现在线时间和在线用户数据错误,
第1步.可能的原因是当前模板下footer.htm没有包含<!--{eval updatesession();}-->语句。
可以选择手动在footer.htm中添加,或者用原foot.htm覆盖当前footer.htm文件。

第2步.如果站点某些活跃用户出现在在线时间不更新的情况。为了不影响设计逻辑,照以下修改updatesession()函数:

找到function_core.php的第66行附近
  • if($_G['uid'] && TIMESTAMP - $ulastactivity > 21600) {
  •             if($oltimespan && TIMESTAMP - $ulastactivity > 43200) {
  •                      $total = DB::result_first("SELECT total FROM ".DB::table('common_onlinetime')." WHERE uid='$_G[uid]'");
  •                       DB::update('common_member_count', array('oltime' => round(intval($total) / 60)), "uid='$_G[uid]'", 1);
  •              }
  •             dsetcookie('ulastactivity', authcode(TIMESTAMP, 'ENCODE'), 31536000);
  •              DB::update('common_member_status', array('lastip' => $_G['clientip'], 'lastactivity' => TIMESTAMP, 'lastvisit' => TIMESTAMP), "uid='$_G[uid]'", 1);
  • }

复制代码
修改为
  • if($_G['uid'] && TIMESTAMP - $ulastactivity > 21600) {
  •           if($oltimespan && TIMESTAMP - $ulastactivity > 43200) {
  •                    $total = DB::result_first("SELECT total FROM ".DB::table('common_onlinetime')." WHERE uid='$_G[uid]'");
  •                    DB::update('common_member_count', array('oltime' => round(intval($total) / 60)), "uid='$_G[uid]'", 1);
  •                    dsetcookie('ulastactivity', authcode(TIMESTAMP, 'ENCODE'), 31536000);
  •           }
  •          DB::update('common_member_status', array('lastip' => $_G['clientip'], 'lastactivity' => TIMESTAMP, 'lastvisit' => TIMESTAMP), "uid='$_G[uid]'", 1);
  • }

复制代码
鲜花(132) 鸡蛋(3)
 楼主| 东南西北人 发表于 2011-8-19 00:19:34 | 显示全部楼层
【更新】在线时间更新机理分析(附在线时间和在线用户错误的可能出现的原因和解决方法
http://www.discuz.net/thread-2242795-1-1.html
鲜花(177) 鸡蛋(0)
zhouweiwrzh 发表于 2011-8-19 06:52:33 | 显示全部楼层
本帖最后由 三T上人 于 2016-7-22 13:22 编辑 <br /><br />呵呵,楼主写得太专业了,看不明白。我从来没在意过自己的在线时间,只感觉东南西北人不错,所以几乎每天都上来看看,嘿嘿!

SOSO.CC
鲜花(33) 鸡蛋(1)
austzj 发表于 2011-8-22 16:26:28 | 显示全部楼层
本帖最后由 三T上人 于 2016-7-22 13:22 编辑 <br /><br />自己能解决吗?

SOSO.CC
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|关于我们|QQ即时充值|站点统计|手机版|小黑屋|百宝箱|留言|咨询|微信订阅|QQ189615688|东南西北人

GMT+8, 2019-9-22 20:05 , Processed in 0.133252 second(s), 41 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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