V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
workaholic
V2EX  ›  程序员

如何即时的获取到用户的在线状态?回复必谢

  •  
  •   workaholic · 2013-05-24 10:20:47 +08:00 · 4236 次点击
    这是一个创建于 4209 天前的主题,其中的信息可能已经有所发展或是发生改变。
    如题,一个网站,如何即时的知道用户在线或者离线? session有一定的延迟,频繁刷新用户最后活动时间是一个很大的开销,不知道有没有更好的方案?谢谢
    第 1 条附言  ·  2013-05-24 18:40:34 +08:00
    主要难点就是用户真正离线的判断,比如非正常关闭浏览器等
    18 条回复    1970-01-01 08:00:00 +08:00
    cxe2v
        1
    cxe2v  
       2013-05-24 10:30:02 +08:00   ❤️ 1
    试着做一个功能专门记录用户在线状态
    我只是抛个砖,具体我也没做过,不知道这样开销大不大,响应速度怎么样
    zhttty
        2
    zhttty  
       2013-05-24 10:44:26 +08:00   ❤️ 1
    正常的状况下还是能比较及时获取到用户在线状态的,譬如JS检测浏览器的关闭操作,在关闭前发消息。但是非正常状态譬如断网...
    shinwood
        3
    shinwood  
       2013-05-24 11:06:18 +08:00 via iPhone   ❤️ 1
    Discuz! 用得是 InnoDB 的 session 表,对每个动作进行更新,但开销比较大。
    binux
        4
    binux  
       2013-05-24 11:10:38 +08:00   ❤️ 1
    放内存里不就好了
    cloudzhou
        5
    cloudzhou  
       2013-05-24 11:16:35 +08:00   ❤️ 2
    我给你一个现实的解决方案吧,判断用户时间在线基本是用户的各种点击浏览行为,每次点击都可以更新用户的最近活跃时间,一般以最近10分钟(也可以其他时间)来认为这段时间内的用户是在线的,两种方法:
    1)数据库,每个点击都是update用户最近活跃时间,用户是否在线就是看时间是否在范围内,总在线人数就是 count 所有在时间范围内
    这种做法对数据库压力非常的大,所以要善用 nosql,第二种解决方法:
    2)使用redis Sorted sets,逻辑上是一样的,就是有来了就update,然后定时清空超过一定时间的用户,剩下的这个 redis Sorted sets 就都是在线用户了,只需要判断用户是否在这个set里面就可以了

    在现实实践中有很多小技巧,如果人数真的千万级别,那么可以考虑按照一定随机比例来更新状态,存在一定误差,还有对于常驻内存的应用,比如 jvm,可以实现一定的数据结构,先在内部做存储,然后统计到远程数据库或者 nosql,其实这是队列机制的思想。
    cloudzhou
        6
    cloudzhou  
       2013-05-24 11:24:27 +08:00   ❤️ 1
    第三种更加简单的方法:
    使用 memcached,然后按照一定的生存时间段放入 cache,
    如果这个用户在cache内,说明是在线的,如果没有那么不在线。
    对于用户的每次浏览行为,都是update新的cache,没有的话就新建cache
    这种方法有缺点,没办法列出所有在线用户。
    tysx
        7
    tysx  
       2013-05-24 13:07:12 +08:00   ❤️ 1
    每个用户发起一Ajax,服务器不返回任何东西一直保持连接。这样是最精确的
    shiny
        8
    shiny  
       2013-05-24 13:11:07 +08:00   ❤️ 1
    试试长连接
    saharabear
        9
    saharabear  
       2013-05-24 13:13:53 +08:00   ❤️ 1
    http不能做到很好地支持准确的在线状态。
    chemzqm
        10
    chemzqm  
       2013-05-24 13:18:58 +08:00   ❤️ 1
    nodejs engine.io长连接,开销不大
    Mihuwa
        11
    Mihuwa  
       2013-05-24 13:54:01 +08:00   ❤️ 1
    谷歌分析有“实时”功能

    可以直接看到当前在线数,动作以及其它详细信息。
    workaholic
        12
    workaholic  
    OP
       2013-05-24 18:33:08 +08:00
    @cloudzhou 恩,我现在的实现方式就是这样,但是还不够即时,正如@saharabear 所说。我现在的程序是当执行入口文件(所有动作都经过这里,bootstrape.php)时就去更新该用户的最近活动时间
    saharabear
        13
    saharabear  
       2013-05-24 18:37:50 +08:00   ❤️ 1
    @workaholic 我试过每5秒让客户端去"ping"一下服务器端,最后发现服务器端用node挺合适,但客户端开销大。用长连接也是一条路子。
    workaholic
        14
    workaholic  
    OP
       2013-05-24 18:43:35 +08:00
    @saharabear 我在用xmpp做一个在在线客服,需要准确把握客服的在线状态,否则会造成访客获取到了客服但是客服已经离线了的可能。长连接也是有这个问题
    atreein
        15
    atreein  
       2013-05-24 18:56:52 +08:00   ❤️ 1
    @shinwood Discuz过去用的是Heap(memory)引擎的user_session表
    chemhack
        16
    chemhack  
       2013-05-24 22:22:26 +08:00   ❤️ 1
    @workaholic websocket呗,在服务器监听connect/close事件就行了
    saharabear
        17
    saharabear  
       2013-05-25 00:39:20 +08:00   ❤️ 1
    @workaholic 我正在考虑xmpp做一个在线隐天,这个东西没有js的api处理在线状态?(我还没开始这个需求)
    workaholic
        18
    workaholic  
    OP
       2013-05-25 07:40:40 +08:00
    @saharabear 有的,Strophe.js
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2783 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 11:46 · PVG 19:46 · LAX 03:46 · JFK 06:46
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.