V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
Comdex
V2EX  ›  问与答

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

  •  
  •   Comdex · 2014-08-05 20:41:33 +08:00 · 6128 次点击
    这是一个创建于 3756 天前的主题,其中的信息可能已经有所发展或是发生改变。
    如题。。。如果session设置7天才过期,那如何判断用户什么时候在线离线?至于最近登录时间这个在用户表设个字段保存登录时间用户登录时即保存时间,但如果用户不直接注销退出第二天又因为session自动登录了,那怎么确定他的登录时间?LZ是web开发菜鸟请大家指点一下
    18 条回复    2014-08-06 09:26:02 +08:00
    spance
        1
    spance  
       2014-08-05 20:53:29 +08:00   ❤️ 1
    对于http下的web应用而言,是否在线很难准确判断,http本身无状态,且大多数都短连接。

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

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

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

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

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

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

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

    @spance
    在 web qq 中,会定时向服务器发起长连接请求,有新消息或者若干时间后将会返回新消息或者正常状态码。
    siteshen
        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
    ityao
        15
    ityao  
       2014-08-06 07:49:19 +08:00   ❤️ 1
    socket长链接,掉线就更新用户状态
    Comdex
        16
    Comdex  
    OP
       2014-08-06 08:54:53 +08:00
    谢谢大家了,看到了很多解决的方法很受用。。。
    mornlight
        17
    mornlight  
       2014-08-06 09:22:43 +08:00   ❤️ 1
    HTTP要做到精确判断应该是用长连接或者长轮询,耗资源,意义不大。我觉得大家说的用某个阀值来判断挺好的,这种东西要精确了干嘛呢
    Comdex
        18
    Comdex  
    OP
       2014-08-06 09:26:02 +08:00
    @mornlight 正是准备采取阀值大约地判断
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1998 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 00:41 · PVG 08:41 · LAX 16:41 · JFK 19:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.