最近在论坛上出现了许多站点的用户在线时间,或者在线用户的列表出现错误数据。针对以上现象,我简单介绍下论坛更新在线时间和在线用户的机理。
所有的操作都在模板文件footer.htm中的一个不起眼的一条语句<!--{eval updatesession();}-->
<!--{eval updatesession();}-->调用的是function_core.php中的updatesession函数。
复制代码
$oltimespan = $_G['setting']['oltimespan'];对应的值是后台全局--站点功能--其他--用户在线时间更新时长(分钟)的值。
复制代码
如果是会员登录论坛,判断最近更新时间与当前时间的差大于用户在线时间更新时长时,会更新common_onlinetime表(记录会员在线时间)里对应用户的对应字段的值,若没有对应用户,则添加一条记录。
复制代码
然后程序开始更新session(针对所有用户,包括未登录的游客),将session数据存到common_session表里。
复制代码
最后根据用户最近的更新的时间,将计算出的用户在线时间,更新到common_member_count表(统计用户记录信息表)里,我们看到的在线时间就是从此表里读取出来的,并且记录当前时间为用户最近活跃的时间。(注意:common_member_count表中的在线时间是每12个小时更新一次)
以上有两个关键点:
在线时间的统计是由该函数执行和保存的,在线会员显示是直接读取的common_session表中的数据
此问题已得到解决.论坛每15分钟统计一次论坛在线情况.如仍有用户出现此问题请在本帖后跟帖描述您的具体情况,我们会在第一时间给予解决.
程序是每15分钟更新一次数据库也就是说.当您登陆论坛时 程序在您登陆之的前一分钟更新过SESSION 缓存,那么您在接下来的13分钟内都会显示离线,直至第二次程序再次运行更新SESSION此时,您的状态会显示在线!
PS: 只开着网页没有进行任何操作是不会更新在线时间的.因为SESSION存在生命周期!
所有的操作都在模板文件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'];
- 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);
- }
- 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;
- 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;
- }
以上有两个关键点:
在线时间的统计是由该函数执行和保存的,在线会员显示是直接读取的common_session表中的数据
此问题已得到解决.论坛每15分钟统计一次论坛在线情况.如仍有用户出现此问题请在本帖后跟帖描述您的具体情况,我们会在第一时间给予解决.
程序是每15分钟更新一次数据库也就是说.当您登陆论坛时 程序在您登陆之的前一分钟更新过SESSION 缓存,那么您在接下来的13分钟内都会显示离线,直至第二次程序再次运行更新SESSION此时,您的状态会显示在线!
PS: 只开着网页没有进行任何操作是不会更新在线时间的.因为SESSION存在生命周期!
另外,请不再次发帖子说自己的时间不正确,请您理解在线时间更新原理.
转载http://bbs.cnliti.com/thread-75557-1-1.html
最近在论坛上出现了许多站点的用户在线时间,或者在线用户的列表出现错误数据。针对以上现象,我简单介绍下论坛更新在线时间和在线用户的机理。
所有的操作都在模板文件footer.htm中的一个不起眼的一条语句<!--{eval updatesession();}-->
<!--{eval updatesession();}-->调用的是function_core.php中的updatesession函数。
复制代码
$oltimespan = $_G['setting']['oltimespan'];对应的值是后台全局--站点功能--其他--用户在线时间更新时长(分钟)的值。
复制代码
如果是会员登录论坛,判断最近更新时间与当前时间的差大于用户在线时间更新时长时,会更新common_onlinetime表(记录会员在线时间)里对应用户的对应字段的值,若没有对应用户,则添加一条记录。
复制代码
然后程序开始更新session(针对所有用户,包括未登录的游客),将session数据存到common_session表里。
复制代码
最后根据用户最近的更新的时间,将计算出的用户在线时间,更新到common_member_count表(统计用户记录信息表)里,我们看到的在线时间就是从此表里读取出来的,并且记录当前时间为用户最近活跃的时间。(注意:common_member_count表中的在线时间是每12个小时更新一次)
以上有两个关键点:
在线时间的统计是由该函数执行和保存的,在线会员显示是直接读取的common_session表中的数据
此问题已得到解决.论坛每15分钟统计一次论坛在线情况.如仍有用户出现此问题请在本帖后跟帖描述您的具体情况,我们会在第一时间给予解决.
程序是每15分钟更新一次数据库也就是说.当您登陆论坛时 程序在您登陆之的前一分钟更新过SESSION 缓存,那么您在接下来的13分钟内都会显示离线,直至第二次程序再次运行更新SESSION此时,您的状态会显示在线!
PS: 只开着网页没有进行任何操作是不会更新在线时间的.因为SESSION存在生命周期!
另外,请不再次发帖子说自己的时间不正确,请您理解在线时间更新原理.
所有的操作都在模板文件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'];
- 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);
- }
- 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;
- 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;
- }
以上有两个关键点:
在线时间的统计是由该函数执行和保存的,在线会员显示是直接读取的common_session表中的数据
此问题已得到解决.论坛每15分钟统计一次论坛在线情况.如仍有用户出现此问题请在本帖后跟帖描述您的具体情况,我们会在第一时间给予解决.
程序是每15分钟更新一次数据库也就是说.当您登陆论坛时 程序在您登陆之的前一分钟更新过SESSION 缓存,那么您在接下来的13分钟内都会显示离线,直至第二次程序再次运行更新SESSION此时,您的状态会显示在线!
PS: 只开着网页没有进行任何操作是不会更新在线时间的.因为SESSION存在生命周期!
另外,请不再次发帖子说自己的时间不正确,请您理解在线时间更新原理.