如何为网站做个判断用户是否在线或用户最近登录时间的功能?

2014-08-05 20:41:33 +08:00
 Comdex
如题。。。如果session设置7天才过期,那如何判断用户什么时候在线离线?至于最近登录时间这个在用户表设个字段保存登录时间用户登录时即保存时间,但如果用户不直接注销退出第二天又因为session自动登录了,那怎么确定他的登录时间?LZ是web开发菜鸟请大家指点一下
6127 次点击
所在节点    问与答
18 条回复
spance
2014-08-05 20:53:29 +08:00
对于http下的web应用而言,是否在线很难准确判断,http本身无状态,且大多数都短连接。

可以近似的实现,首先要有一个池,当携带session的请求到达时,在池里面找这个用户的信息,有就把时间更新为当前,没有就新增上去。
另外一个线程定时的扫描这个池,当前时间-时间字段大于闸值就删掉,相当于做一个过期队列一样。
所以,在线用户就是这个池里面的用户信息了。
Comdex
2014-08-05 20:58:07 +08:00
@spance 这个定时比较难把控。。。。
Comdex
2014-08-05 20:59:39 +08:00
@spance 若只做简单的用户最近登录时间还有没有更好的方法?
spance
2014-08-05 21:04:55 +08:00
@Comdex
这个就是经验估计。事实上qq在线也是一个估计值,某人突然掉线后,tcp状态变化服务器一定是敏感的,事实上别人看到的它的状态变化大概需要几十秒到1分钟的样子。
GhostFlying
2014-08-05 21:06:41 +08:00
常见的似乎是在用户任意活动时更新他的最后活动时间,然后最后活动时间开始的一定时间内就认为用户在线
Comdex
2014-08-05 21:09:48 +08:00
@GhostFlying 那最近登录时间呢?
xiaojj
2014-08-05 21:34:48 +08:00
用户加个字段,没访问一次网站任意页面,修改该字段为当前时间戳
在线用户就是时间戳小于当前时间几分钟的用户
Comdex
2014-08-05 21:45:11 +08:00
@xiaojj 那么如果我要做最近登录时间呢?因为session保持时间长不知道用户那个行为是离开后又登录。。。
shiznet
2014-08-05 23:04:53 +08:00
为什么要判断用户什么时候登陆过呢? 这个是要做统计需求还是说登陆操作有额外的提示?

我有个大致的想法:就是记录本次访问时间与上次访问时间做差,设定一个阈值,如果两次访问时间超过该阈值就假定为重新登陆操作(主动登陆或者cookie过来)。不过这样还是会有偏差。
sxlzll
2014-08-05 23:08:53 +08:00
我都是做心跳的,每次或定时更新数据库,如果logout 5分钟(精度自定义)内没有数据,就插一条(login和logout都是sysdate),如果有时间就update logout
GhostFlying
2014-08-05 23:18:28 +08:00
@Comdex 既然超时就认为不在线,那么下次重新刷新在线时间的时候就可以认为是重新登录
lyragosa
2014-08-05 23:37:41 +08:00
不谈理论 只谈实际,我的网站是这么做的

每个用户访问任何任何一页,都会向一个特定的表(MEMORY表,避免负载)写入一条信息
包括sesssionid,userid,useragent,ip和最后活动时间等信息。

每天晚上2点 用crontab将一天之前的数据删除。

如果需要取出最近在线的用户,将这个表以最后活动时间排序,找出用户ID即可

判定在线的办法,是查这个表的活动时间并对照当前时间,超出一定则判定离线。

我的网站是传统HTML4 + PHP + MYSQL。
zxc111
2014-08-06 00:02:53 +08:00
用户每次刷新页面后往数据库塞时间戳或者在cookie中记录时间,如果离设定的值过远的话,判断为离线

@spance
在 web qq 中,会定时向服务器发起长连接请求,有新消息或者若干时间后将会返回新消息或者正常状态码。
siteshen
2014-08-06 00:20:14 +08:00
在线用户统计:使用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
ityao
2014-08-06 07:49:19 +08:00
socket长链接,掉线就更新用户状态
Comdex
2014-08-06 08:54:53 +08:00
谢谢大家了,看到了很多解决的方法很受用。。。
mornlight
2014-08-06 09:22:43 +08:00
HTTP要做到精确判断应该是用长连接或者长轮询,耗资源,意义不大。我觉得大家说的用某个阀值来判断挺好的,这种东西要精确了干嘛呢
Comdex
2014-08-06 09:26:02 +08:00
@mornlight 正是准备采取阀值大约地判断

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/126291

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX