1
spance 2014-08-05 20:53:29 +08:00 1
对于http下的web应用而言,是否在线很难准确判断,http本身无状态,且大多数都短连接。
可以近似的实现,首先要有一个池,当携带session的请求到达时,在池里面找这个用户的信息,有就把时间更新为当前,没有就新增上去。 另外一个线程定时的扫描这个池,当前时间-时间字段大于闸值就删掉,相当于做一个过期队列一样。 所以,在线用户就是这个池里面的用户信息了。 |
4
spance 2014-08-05 21:04:55 +08:00 1
@Comdex
这个就是经验估计。事实上qq在线也是一个估计值,某人突然掉线后,tcp状态变化服务器一定是敏感的,事实上别人看到的它的状态变化大概需要几十秒到1分钟的样子。 |
5
GhostFlying 2014-08-05 21:06:41 +08:00 1
常见的似乎是在用户任意活动时更新他的最后活动时间,然后最后活动时间开始的一定时间内就认为用户在线
|
6
Comdex OP @GhostFlying 那最近登录时间呢?
|
7
xiaojj 2014-08-05 21:34:48 +08:00 1
用户加个字段,没访问一次网站任意页面,修改该字段为当前时间戳
在线用户就是时间戳小于当前时间几分钟的用户 |
9
shiznet 2014-08-05 23:04:53 +08:00 1
为什么要判断用户什么时候登陆过呢? 这个是要做统计需求还是说登陆操作有额外的提示?
我有个大致的想法:就是记录本次访问时间与上次访问时间做差,设定一个阈值,如果两次访问时间超过该阈值就假定为重新登陆操作(主动登陆或者cookie过来)。不过这样还是会有偏差。 |
10
sxlzll 2014-08-05 23:08:53 +08:00 1
我都是做心跳的,每次或定时更新数据库,如果logout 5分钟(精度自定义)内没有数据,就插一条(login和logout都是sysdate),如果有时间就update logout
|
11
GhostFlying 2014-08-05 23:18:28 +08:00 1
@Comdex 既然超时就认为不在线,那么下次重新刷新在线时间的时候就可以认为是重新登录
|
12
lyragosa 2014-08-05 23:37:41 +08:00 1
不谈理论 只谈实际,我的网站是这么做的
每个用户访问任何任何一页,都会向一个特定的表(MEMORY表,避免负载)写入一条信息 包括sesssionid,userid,useragent,ip和最后活动时间等信息。 每天晚上2点 用crontab将一天之前的数据删除。 如果需要取出最近在线的用户,将这个表以最后活动时间排序,找出用户ID即可 判定在线的办法,是查这个表的活动时间并对照当前时间,超出一定则判定离线。 我的网站是传统HTML4 + PHP + MYSQL。 |
13
zxc111 2014-08-06 00:02:53 +08:00 1
用户每次刷新页面后往数据库塞时间戳或者在cookie中记录时间,如果离设定的值过远的话,判断为离线
@spance 在 web qq 中,会定时向服务器发起长连接请求,有新消息或者若干时间后将会返回新消息或者正常状态码。 |
14
siteshen 2014-08-06 00:20:14 +08:00 1
在线用户统计:使用redis的sorted set,以下流程假定key为"online-users",{{}}为变量替换。
1. web端加一个middleware,判断用户登录后,往redis里面塞一条记录: zadd online-users {{current_timestamp}} {{user_id}} 2. 在线用户数:zlexcount online-users {{timestamp-1min)}} {{timestamp}} 3. 在线用户列表:zrevrangebyscore online-users {{timestamp-1min)}} {{timestamp}} 参考 http://redis.io/commands#sorted_set |
15
ityao 2014-08-06 07:49:19 +08:00 1
socket长链接,掉线就更新用户状态
|
16
Comdex OP 谢谢大家了,看到了很多解决的方法很受用。。。
|
17
mornlight 2014-08-06 09:22:43 +08:00 1
HTTP要做到精确判断应该是用长连接或者长轮询,耗资源,意义不大。我觉得大家说的用某个阀值来判断挺好的,这种东西要精确了干嘛呢
|