实现统计在线用户的几种方式

先说说一些平常的做法:

一,每次用户操作更新其在线时间

这个方法很直接,在用户表里加一个字段update_time,每次用户进行操作,都更新这个字段为当前时间,一般是在一个被所有Action继承的基类里写这个操作。

然后定义一个过期时间,比如10分钟,表示10分钟没进行任何操作的用户默认为不在线。这样,统计当前在线用户的sql语句大概是这样selectcount(*)fromthink_userwhereupdate_time>now()-10*60

复制代码优点:实现简单,通俗易懂

缺点:1,对“在线”的定义模糊,万一用户看一篇文章时间比较长,10分钟内没进行任何操作,他就被忽略了;2,如果user表数据量很大,那效率将极差

二,将在线用户单独放入一张表

对于方法一的改进。新建一张表think_inline,字段有user_id、update_time,每次用户操作时,先判断表里有没有该用户的记录,没有则新增,有就更新update_time。

并同时加上删除失效数据操作deletefromthink_inlinewhereupdate_time

复制代码这样,统计在线就可以直接count这张表就行了。而且这表的数据量不会很大(至少要比用户表小的多)

优点:减少数据库压力

缺点:仍然对“在线”的定义不准确

三,用JS定时器

这个方法是综合了一和二。新建一张表think_inline,也是在基类中定义每次用户操作时更新时间,参考二的做法。

不同之处是,在每个html模板里,加上一个js定时器,setInterval('updateTime', 10*3600);每隔10分钟发送一次ajax请求,更新update_time字段。这样,即使用户在一个页面停留时间过长,也不会被误认为不在线了。并且可以通过减少请求的间隔,来增加精确度,当然了,对服务器的压力就更大了。

优点:对在线的判断较为准确

缺点:仍然不能既精确又不增加服务器压力,必须在两者之间进行取舍。

四,使用TP的SessionDb驱动进行最优化设计

这也就是网上有人说的session存入数据库的方法,这种方法优点很多。目前,LZ就是用的这个。

具体做法是。。。有50个评论,我就公布,当然了,跟百度的那些复制粘贴的例子不一样,会有深入解析哦!

没多少人看啊,先写一些。

1,为什么要将session存入数据库?

session是存储在服务器的一组临时数据。一般情况下,我们在做用户登录时,会将用户数据存入session。这样,在任何页面都可以方便调用,而且每个客户端会产生唯一的session_id,不会混肴。并且在关闭浏览器后,服务器会有session回收机制,自动删除过期session。

这是session的优点:唯一性、方便调用、不会过多占用资源。但是也有缺点:在客户端是以cookie方式保存的,禁用cookie就没用了。

那么,服务器是如何存放session的呢?他是默认将session以文件的方式保存在硬盘上的。可是,对于我们码农来说,操作数据库要比读文件方便的多,并且可以对session数据进行各种操作。

而统计在线用户人数就是通过统计有多少条session记录来实现的。

2,如何把session存入数据库?

TP的SessionDb驱动就实现了这个功能。原理就是通过改写PHP默认的session操作来实现,核心函数session_set_save_handler(),有兴趣的可以研究一下。该驱动将session的增、读、取、和删都放入了数据库。

使用方法也很简单:1,建表,驱动的注释里的sql语句运行下就好

2,添加配置://Session配置

'SESSION_TYPE'=>'db',//数据库存储session

'SESSION_TABLE'=>'think_session',//存session的表

'SESSION_EXPIRE'=>600,//session过期时间

复制代码这样,只要我们在程序里使用了session()函数,数据库里就会有记录。

3,利用数据库session实现统计在线用户

1,统计在线总人数$map=array('session_expire'=>array('gt',NOW_TIME));

$inline=D('Session')->where($map)->count();

复制代码2,统计游客(未登录)人数$map=array('session_expire'=>array('gt',NOW_TIME),'session_data'=>array('eq',''));

$huiyuan=D('Session')->where($map)->count();

复制代码3,统计会员(已登录)人数$map=array('session_expire'=>array('gt',NOW_TIME),'session_data'=>array('neq',''));

$huiyuan=D('Session')->where($map)->count();

复制代码4,判断一个用户是否在线。

在用户表里新增一个字段:session_id。

(1)在登录操作里,保存该用户的session_id,$session_id=session_id();

D('User')->where(array('id'=>$user_id))->save('session_id'=>$session_id);

复制代码(2)检查session表里是否存在该session_id,未过期并且有值,$map=array('session_id'=>$session_id,'session_expire'=>array('gt',NOW_TIME),'session_data'=>array('neq',''));

$res=D('Session')->where($map)->find();

if($res){dump('该用户在线。')}else{dump('该用户不在线。')}

复制代码

码字太麻烦啦,先写这么多,后面总结该方法的几大优点以及注意事项。

4,总结

1,实现步骤:用户表新增字段保存session_id;使用TP的SessionDb驱动。是不是很简单?

2,优点

(1)比上面三种方法对数据库和服务器的压力都小,操作简单

(2)能够区分在线用户是会员还是游客(session_data字段是否有值),discuz就是这样做的

(3)可以通过删除某用户的session记录,实现将其“踢下线”的功能

3,缺点

(1)仍然不能精确统计,只能说,XX秒内在线多少人

4,注意事项

(1)由于该方法的SessionDb驱动必须使用session()函数才能触发,所以必须配置自动开启session(默认就是开启)。TP在执行流程里会使用session()函数,所以你什么都不写,session数据也会存入数据库。

(2)因为数据库的session数据是不会自己删除的,所以对于过期的数据,必须调用session()方法才会删。

这也就意味着,如果你的网站一个人都没有访问,那么数据库的过期session记录会一直存在。

也就是由于这种机制,对于一些突发事件(用户直接X浏览器、直接关机、发生地震……),在其关闭浏览器的一段时间(session过期时间)后,其他用户对网站的访问,会触发session回收,删除过期记录。所以,就不怕统计出来的数据不准确了。

当然了,就算没人访问,你也可以在count时加上session_expire>time()来统计。

但是也有误差,就是session过期时间,5分钟后过期,就有5分钟的误差。时间设的越小,对数据库的操作就越频繁;越大,精确度就越低。

(3)这个session过期时间就意味着,如果用户5分钟内不进行任何操作,其就会自动退出登录。所以,为了用户体验好,请加上cookie自动登录功能。目前官网就是这么做的。

(4)评论里有人提到,验证码也会存入session,所以我们判断的时候,就不能值统计有值的记录了。

需要先获取有值的数据,再判断里面有没有保存用户信息的参数名。虽然session_data字段是用二进制存储的,但是查询出来就是一个字符串。

比如,我们用的user下标来保存的用户信息,session('user',$data);//用户登录信息

//获取真实会员数

//查询有值的session记录

$list=D('Session')->where(array('session_data'=>array('NEQ',''),'session_expire'=>array('lt',NOW_TIME)))->select();

//判断值里是否有会员标识

foreach($listas$k=>$value){

if(strpos($value['session_data'],'user')===false){

$count++;

}

dump($count);//真实会员人数

}

复制代码

(5)由于每种浏览器都有各自的session机制,所以,如果一个人在一台电脑上同时开了5种浏览器,则数据库会保存5条不同的记录

实际使用时,仍需要考虑搜索引擎的误差。在其抓取我们的页面时,也会产生session。

五,最终结论

由于HTTP协议的限制:请求完成后就会断开与客户端的连接。所以实际上,我们根本无法精确而实时地统计在线人数

尽管有各种各样的方法来增加统计的精确度,然而都是治标不治本。

唯有放弃HTTP协议,使用“长连接”的链接方式,才能精确判断用户在还是离

转自 http://www.thinkphp.cn/topic/3217.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容

  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,865评论 6 13
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,598评论 18 139
  • Php:脚本语言,网站建设,服务器端运行 PHP定义:一种服务器端的HTML脚本/编程语言,是一种简单的、面向对象...
    廖马儿阅读 2,116评论 2 38
  • 1、memcache的概念? Memcache是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨...
    桖辶殇阅读 2,224评论 2 12
  • 大早上去换数据线,小老板气坏了,说我这刚开张,你这样我这一天都得这样,放那下午给你换! 这迷信可不能算讲究啊,真受...
    纵情嬉戏天地间阅读 210评论 0 0