亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

基于Redis的在線用戶列表解決方案

系統 2431 0

前言:

由于項目需求,需要在集群環境下實現在線用戶列表的功能,并依靠在線列表實現用戶單一登陸(同一賬戶只能一處登陸)功能:

在單機環境下,在線列表的實現方案可以采用SessionListener來完成,當有Session創建和銷毀的時候做相應的操作即可完成功能及將相應的Session的引用存放于內存中,由于持有了所有的Session的引用,故可以方便的實現用戶單一登陸的功能(比如在第二次登陸的時候使之前登陸的賬戶所在的Session失效)。

而在集群環境下,由于用戶的請求可能分布在不同的Web服務器上,繼續將在線用戶列表儲存在單機內存中已經不能滿足需要,不同的Web服務器將會產生不同的在線列表,并且不能有效的實現單一用戶登陸的功能,因為某一用戶可能并不在接受到退出請求的Web服務器的在線用戶列表中(在集群中的某臺服務器上完成的登陸操作,而在其他服務器上完成退出操作)。

現有解決方案:

1.將用戶的在線情況記錄進入數據庫中,依靠數據庫完成對登陸狀況的檢測

2.將在線列表放在一個公共的緩存服務器上

由于緩存服務器可以為緩存內容設置指定有效期,可以方便實現Session過期的效果,以及避免讓數據庫的讀寫性能成為系統瓶頸等原因,我們采用了Redis來作為緩存服務器用于實現該功能。

單機環境下的解決方案:

基于HttpSessionListener:

      
         1
      
      
        import
      
      
         java.util.Date;


      
      
         2
      
      
        import
      
      
         java.util.Hashtable;


      
      
         3
      
      
        import
      
      
         java.util.Iterator;


      
      
         4
      
      
        import
      
      
         javax.servlet.http.HttpSession;


      
      
         5
      
      
        import
      
      
         javax.servlet.http.HttpSessionEvent;


      
      
         6
      
      
        import
      
      
         javax.servlet.http.HttpSessionListener;


      
      
         7
      
      
        import
      
      
         com.xxx.common.util.StringUtil;


      
      
         8
      
      
        /**
      
      
         9
      
      
         * 


      
      
        10
      
      
         * @ClassName: SessionListener


      
      
        11
      
      
         * @Description: 記錄所有登陸的Session信息,為在線列表做基礎


      
      
        12
      
      
         * 
      
      
        @author
      
      
         libaoting


      
      
        13
      
      
         * @date 2013-9-18 09:35:13


      
      
        14
      
      
         *


      
      
        15
      
      
        */
      
      
        16
      
      
        public
      
      
        class
      
       SessionListener 
      
        implements
      
      
         HttpSessionListener {


      
      
        17
      
      
        //
      
      
        在線列表<uid,session>
      
      
        18
      
      
        private
      
      
        static
      
       Hashtable<String,HttpSession> sessionList = 
      
        new
      
       Hashtable<String, HttpSession>
      
        ();


      
      
        19
      
      
        public
      
      
        void
      
      
         sessionCreated(HttpSessionEvent event) {


      
      
        20
      
      
        //
      
      
        不做處理,只處理登陸用戶的列表
      
      
        21
      
      
            }


      
      
        22
      
      
        public
      
      
        void
      
      
         sessionDestroyed(HttpSessionEvent event) {


      
      
        23
      
      
                removeSession(event.getSession());


      
      
        24
      
      
            }


      
      
        25
      
      
        public
      
      
        static
      
      
        void
      
      
         removeSession(HttpSession session){


      
      
        26
      
      
        if
      
      (session == 
      
        null
      
      
        ){


      
      
        27
      
      
        return
      
      
         ;


      
      
        28
      
      
                }


      
      
        29
      
               String uid=(String)session.getAttribute("clientUserId");
      
        //
      
      
        已登陸狀態會將用戶的UserId保存在session中
      
      
        30
      
      
        if
      
      (!StringUtil.isBlank(uid)){
      
        //
      
      
        判斷是否登陸狀態
      
      
        31
      
      
                    removeSession(uid);


      
      
        32
      
      
                }


      
      
        33
      
      
            }


      
      
        34
      
      
        public
      
      
        static
      
      
        void
      
      
         removeSession(String uid){


      
      
        35
      
               HttpSession session =
      
         sessionList.get(uid);


      
      
        36
      
      
        try
      
      
        {


      
      
        37
      
                   sessionList.remove(uid);
      
        //
      
      
        先執行,防止session.invalidate()報錯而不執行
      
      
        38
      
      
        if
      
      (session != 
      
        null
      
      
        ){


      
      
        39
      
      
                        session.invalidate();


      
      
        40
      
      
                    }


      
      
        41
      
               }
      
        catch
      
      
         (Exception e) {


      
      
        42
      
                   System.out.println("Session invalidate error!"
      
        );


      
      
        43
      
      
                }


      
      
        44
      
      
            }


      
      
        45
      
      
        public
      
      
        static
      
      
        void
      
      
         addSession(String uid,HttpSession session){


      
      
        46
      
      
                sessionList.put(uid, session);


      
      
        47
      
      
            }


      
      
        48
      
      
        public
      
      
        static
      
      
        int
      
      
         getSessionCount(){


      
      
        49
      
      
        return
      
      
         sessionList.size();


      
      
        50
      
      
            }


      
      
        51
      
      
        public
      
      
        static
      
       Iterator<HttpSession>
      
         getSessionSet(){


      
      
        52
      
      
        return
      
      
         sessionList.values().iterator();


      
      
        53
      
      
            }


      
      
        54
      
      
        public
      
      
        static
      
      
         HttpSession getSession(String id){


      
      
        55
      
      
        return
      
      
         sessionList.get(id);


      
      
        56
      
      
            }


      
      
        57
      
      
        public
      
      
        static
      
      
        boolean
      
      
         contains(String uid){


      
      
        58
      
      
        return
      
      
         sessionList.containsKey(uid);


      
      
        59
      
      
            }


      
      
        60
      
      
        /**
      
      
        61
      
      
             * 


      
      
        62
      
      
             * @Title: isLoginOnThisSession


      
      
        63
      
      
             * @Description: 檢測是否已經登陸


      
      
        64
      
      
             * 
      
      
        @param
      
      
        @param
      
      
         uid 用戶UserId


      
      
        65
      
      
             * 
      
      
        @param
      
      
        @param
      
      
         sid 發起請求的用戶的SessionId


      
      
        66
      
      
             * 
      
      
        @return
      
      
         boolean true 校驗通過 


      
      
        67
      
      
        */
      
      
        68
      
      
        public
      
      
        static
      
      
        boolean
      
      
         isLoginOnThisSession(String uid,String sid){


      
      
        69
      
      
        if
      
      (uid==
      
        null
      
      ||sid==
      
        null
      
      
        ){


      
      
        70
      
      
        return
      
      
        false
      
      
        ;


      
      
        71
      
      
                }


      
      
        72
      
      
        if
      
      
        (contains(uid)){


      
      
        73
      
                   HttpSession session =
      
         sessionList.get(uid);


      
      
        74
      
      
        if
      
      (session!=
      
        null
      
      &&
      
        session.getId().equals(sid)){


      
      
        75
      
      
        return
      
      
        true
      
      
        ;


      
      
        76
      
      
                    }


      
      
        77
      
      
                }


      
      
        78
      
      
        return
      
      
        false
      
      
        ;


      
      
        79
      
      
            }


      
      
        80
      
       }
    

  用戶的在線狀態全部維護記錄在sessionList中,并且可以通過sessionList獲取到任意用戶的session對象,可以用來完成使指定用戶離線的功能(調用該用戶的session.invalidate()方法)。

用戶登錄的時候調用addSession(uid,session)方法將用戶與其登錄的Session信息記錄至sessionList中,再退出的時候調用removeSession(session) or removeSession(uid)方法,在強制下線的時候調用removeSession(uid)方法,以及一些其他的操作即可實現相應的功能。

基于Redis的解決方案:

該解決方案的實質是將在線列表的所在的內存共享出來,讓集群環境下所有的服務器都能夠訪問到這部分數據,并且將用戶的在線狀態在這塊內存中進行維護。

Redis連接池工具類:

      
          1
      
      
        import
      
      
         java.util.ResourceBundle;


      
      
          2
      
      
        import
      
      
         redis.clients.jedis.Jedis;


      
      
          3
      
      
        import
      
      
         redis.clients.jedis.JedisPool;


      
      
          4
      
      
        import
      
      
         redis.clients.jedis.JedisPoolConfig;


      
      
          5
      
      
        public
      
      
        class
      
      
         RedisPoolUtils {


      
      
          6
      
      
        private
      
      
        static
      
      
        final
      
      
         JedisPool pool;


      
      
          7
      
      
        static
      
      
        {


      
      
          8
      
               ResourceBundle bundle = ResourceBundle.getBundle("redis"
      
        );


      
      
          9
      
               JedisPoolConfig config = 
      
        new
      
      
         JedisPoolConfig();


      
      
         10
      
      
        if
      
       (bundle == 
      
        null
      
      
        ) {    


      
      
         11
      
      
        throw
      
      
        new
      
       IllegalArgumentException("[redis.properties] is not found!"
      
        );    


      
      
         12
      
      
                }


      
      
         13
      
      
        //
      
      
        設置池配置項值  
      
      
         14
      
               config.setMaxActive(Integer.valueOf(bundle.getString("jedis.pool.maxActive"
      
        )));    


      
      
         15
      
               config.setMaxIdle(Integer.valueOf(bundle.getString("jedis.pool.maxIdle"
      
        )));    


      
      
         16
      
               config.setMaxWait(Long.valueOf(bundle.getString("jedis.pool.maxWait"
      
        )));    


      
      
         17
      
               config.setTestOnBorrow(Boolean.valueOf(bundle.getString("jedis.pool.testOnBorrow"
      
        )));    


      
      
         18
      
               config.setTestOnReturn(Boolean.valueOf(bundle.getString("jedis.pool.testOnReturn"
      
        )));


      
      
         19
      
               pool = 
      
        new
      
       JedisPool(config, bundle.getString("redis.ip"),Integer.valueOf(bundle.getString("redis.port"
      
        )) );


      
      
         20
      
      
            }


      
      
         21
      
      
        /**
      
      
         22
      
      
             * 


      
      
         23
      
      
             * @Title: release


      
      
         24
      
      
             * @Description: 釋放連接


      
      
         25
      
      
             * 
      
      
        @param
      
      
        @param
      
      
         jedis


      
      
         26
      
      
             * 
      
      
        @return
      
      
         void


      
      
         27
      
      
             * 
      
      
        @throws
      
      
         28
      
      
        */
      
      
         29
      
      
        public
      
      
        static
      
      
        void
      
      
         release(Jedis jedis){


      
      
         30
      
      
                pool.returnResource(jedis);


      
      
         31
      
      
            }


      
      
         32
      
      
        public
      
      
        static
      
      
         Jedis getJedis(){


      
      
         33
      
      
        return
      
      
         pool.getResource();


      
      
         34
      
      
            }


      
      
         35
      
      
        }


      
      
         36
      
      
        Redis在線列表工具類:


      
      
         37
      
      
        import
      
      
         java.util.ArrayList;


      
      
         38
      
      
        import
      
      
         java.util.Collections;


      
      
         39
      
      
        import
      
      
         java.util.Comparator;


      
      
         40
      
      
        import
      
      
         java.util.Date;


      
      
         41
      
      
        import
      
      
         java.util.List;


      
      
         42
      
      
        import
      
      
         java.util.Set;


      
      
         43
      
      
        import
      
      
         net.sf.json.JSONObject;


      
      
         44
      
      
        import
      
      
         net.sf.json.JsonConfig;


      
      
         45
      
      
        import
      
      
         net.sf.json.processors.JsonValueProcessor;


      
      
         46
      
      
        import
      
      
         cn.sccl.common.util.StringUtil;


      
      
         47
      
      
        import
      
      
         com.xxx.common.util.JsonDateValueProcessor;


      
      
         48
      
      
        import
      
      
         com.xxx.user.model.ClientUser;


      
      
         49
      
      
        import
      
      
         redis.clients.jedis.Jedis;


      
      
         50
      
      
        import
      
      
         redis.clients.jedis.Pipeline;


      
      
         51
      
      
        import
      
      
         tools.Constants;


      
      
         52
      
      
        /**
      
      
         53
      
      
         * 


      
      
         54
      
      
         * Redis緩存中存放兩組key:


      
      
         55
      
      
         * 1.SID_PREFIX開頭,存放登陸用戶的SessionId與ClientUser的Json數據


      
      
         56
      
      
         * 2.UID_PREFIX開頭,存放登錄用戶的UID與SessionId對于的數據


      
      
         57
      
      
         *


      
      
         58
      
      
         * 3.VID_PREFIX開頭,存放位于指定頁面用戶的數據(與Ajax一起使用,用于實現指定頁面同時瀏覽人數的限制功能)


      
      
         59
      
      
         * 


      
      
         60
      
      
         * @ClassName: OnlineUtils


      
      
         61
      
      
         * @Description: 在線列表操作工具類


      
      
         62
      
      
         * 
      
      
        @author
      
      
         BuilderQiu


      
      
         63
      
      
         * @date 2014-1-9 上午09:25:43


      
      
         64
      
      
         *


      
      
         65
      
      
        */
      
      
         66
      
      
        public
      
      
        class
      
      
         OnlineUtils {


      
      
         67
      
      
        //
      
      
        KEY值根據SessionID生成    
      
      
         68
      
      
        private
      
      
        static
      
      
        final
      
       String SID_PREFIX = "online:sid:"
      
        ;


      
      
         69
      
      
        private
      
      
        static
      
      
        final
      
       String UID_PREFIX = "online:uid:"
      
        ;


      
      
         70
      
      
        private
      
      
        static
      
      
        final
      
       String VID_PREFIX = "online:vid:"
      
        ;


      
      
         71
      
      
        private
      
      
        static
      
      
        final
      
      
        int
      
       OVERDATETIME = 30 * 60
      
        ;


      
      
         72
      
      
        private
      
      
        static
      
      
        final
      
      
        int
      
       BROADCAST_OVERDATETIME = 70;
      
        //
      
      
        ax每60秒發起一次,超過BROADCAST_OVERDATETIME時間長度未發起表示已經離開該頁面
      
      
         73
      
      
        public
      
      
        static
      
      
        void
      
      
         login(String sid,ClientUser user){


      
      
         74
      
               Jedis jedis =
      
         RedisPoolUtils.getJedis();


      
      
         75
      
               jedis.setex(SID_PREFIX+
      
        sid, OVERDATETIME, userToString(user));


      
      
         76
      
               jedis.setex(UID_PREFIX+
      
        user.getId(), OVERDATETIME, sid);


      
      
         77
      
      
                RedisPoolUtils.release(jedis);


      
      
         78
      
      
            }


      
      
         79
      
      
        public
      
      
        static
      
      
        void
      
      
         broadcast(String uid,String identify){


      
      
         80
      
      
        if
      
      (uid==
      
        null
      
      ||"".equals(uid)) 
      
        //
      
      
        異常數據,正常情況下登陸用戶才會發起該請求
      
      
         81
      
      
        return
      
      
         ;


      
      
         82
      
               Jedis jedis =
      
         RedisPoolUtils.getJedis();


      
      
         83
      
               jedis.setex(VID_PREFIX+identify+":"+
      
        uid, BROADCAST_OVERDATETIME, uid);


      
      
         84
      
      
                RedisPoolUtils.release(jedis);


      
      
         85
      
      
            }


      
      
         86
      
      
        private
      
      
        static
      
      
         String userToString(ClientUser user){


      
      
         87
      
               JsonConfig  config = 
      
        new
      
      
         JsonConfig();


      
      
         88
      
               JsonValueProcessor processor = 
      
        new
      
       JsonDateValueProcessor("yyyy-MM-dd HH:mm:ss"
      
        );


      
      
         89
      
               config.registerJsonValueProcessor(Date.
      
        class
      
      
        , processor);


      
      
         90
      
               JSONObject obj =
      
         JSONObject.fromObject(user, config);


      
      
         91
      
      
        return
      
      
         obj.toString();


      
      
         92
      
      
            }


      
      
         93
      
      
        /**
      
      
         94
      
      
             * 


      
      
         95
      
      
             * @Title: logout


      
      
         96
      
      
             * @Description: 退出


      
      
         97
      
      
             * 
      
      
        @param
      
      
        @param
      
      
         sessionId


      
      
         98
      
      
             * 
      
      
        @return
      
      
         void


      
      
         99
      
      
             * 
      
      
        @throws
      
      
        100
      
      
        */
      
      
        101
      
      
        public
      
      
        static
      
      
        void
      
      
         logout(String sid,String uid){


      
      
        102
      
               Jedis jedis =
      
         RedisPoolUtils.getJedis();


      
      
        103
      
               jedis.del(SID_PREFIX+
      
        sid);


      
      
        104
      
               jedis.del(UID_PREFIX+
      
        uid);


      
      
        105
      
      
                RedisPoolUtils.release(jedis);


      
      
        106
      
      
            }


      
      
        107
      
      
        /**
      
      
        108
      
      
             * 


      
      
        109
      
      
             * @Title: logout


      
      
        110
      
      
             * @Description: 退出


      
      
        111
      
      
             * 
      
      
        @param
      
      
        @param
      
      
         UserId  使指定用戶下線


      
      
        112
      
      
             * 
      
      
        @return
      
      
         void


      
      
        113
      
      
             * 
      
      
        @throws
      
      
        114
      
      
        */
      
      
        115
      
      
        public
      
      
        static
      
      
        void
      
      
         logout(String uid){


      
      
        116
      
               Jedis jedis =
      
         RedisPoolUtils.getJedis();


      
      
        117
      
      
        //
      
      
        刪除sid
      
      
        118
      
               jedis.del(SID_PREFIX+jedis.get(UID_PREFIX+
      
        uid));


      
      
        119
      
      
        //
      
      
        刪除uid
      
      
        120
      
               jedis.del(UID_PREFIX+
      
        uid);


      
      
        121
      
      
                RedisPoolUtils.release(jedis);


      
      
        122
      
      
            }


      
      
        123
      
      
        public
      
      
        static
      
      
         String getClientUserBySessionId(String sid){


      
      
        124
      
               Jedis jedis =
      
         RedisPoolUtils.getJedis();


      
      
        125
      
               String user = jedis.get(SID_PREFIX+
      
        sid);


      
      
        126
      
      
                RedisPoolUtils.release(jedis);


      
      
        127
      
      
        return
      
      
         user;


      
      
        128
      
      
            }


      
      
        129
      
      
        public
      
      
        static
      
      
         String getClientUserByUid(String uid){


      
      
        130
      
               Jedis jedis =
      
         RedisPoolUtils.getJedis();


      
      
        131
      
               String user = jedis.get(SID_PREFIX+jedis.get(UID_PREFIX+
      
        uid));


      
      
        132
      
      
                RedisPoolUtils.release(jedis);


      
      
        133
      
      
        return
      
      
         user;


      
      
        134
      
      
            }


      
      
        135
      
      
        /**
      
      
        136
      
      
             * 


      
      
        137
      
      
             * @Title: online


      
      
        138
      
      
             * @Description: 所有的key


      
      
        139
      
      
             * 
      
      
        @return
      
      
         List  


      
      
        140
      
      
             * 
      
      
        @throws
      
      
        141
      
      
        */
      
      
        142
      
      
        public
      
      
        static
      
      
         List online(){


      
      
        143
      
               Jedis jedis =
      
         RedisPoolUtils.getJedis();


      
      
        144
      
               Set online = jedis.keys(SID_PREFIX+"*"
      
        );


      
      
        145
      
      
                RedisPoolUtils.release(jedis);


      
      
        146
      
      
        return
      
      
        new
      
      
         ArrayList(online);


      
      
        147
      
      
            }


      
      
        148
      
      
        /**
      
      
        149
      
      
             * 


      
      
        150
      
      
             * @Title: online


      
      
        151
      
      
             * @Description: 分頁顯示在線列表


      
      
        152
      
      
             * 
      
      
        @return
      
      
         List  


      
      
        153
      
      
             * 
      
      
        @throws
      
      
        154
      
      
        */
      
      
        155
      
      
        public
      
      
        static
      
       List onlineByPage(
      
        int
      
       page,
      
        int
      
       pageSize) 
      
        throws
      
      
         Exception{


      
      
        156
      
               Jedis jedis =
      
         RedisPoolUtils.getJedis();


      
      
        157
      
               Set onlineSet = jedis.keys(SID_PREFIX+"*"
      
        );


      
      
        158
      
               List onlines =
      
        new
      
      
         ArrayList(onlineSet);


      
      
        159
      
      
        if
      
      (onlines.size() == 0
      
        ){


      
      
        160
      
      
        return
      
      
        null
      
      
        ;


      
      
        161
      
      
                }


      
      
        162
      
               Pipeline pip =
      
         jedis.pipelined();


      
      
        163
      
      
        for
      
      
        (Object key:onlines){


      
      
        164
      
      
                    pip.get(getKey(key));


      
      
        165
      
      
                }


      
      
        166
      
               List result =
      
         pip.syncAndReturnAll();


      
      
        167
      
      
                RedisPoolUtils.release(jedis);


      
      
        168
      
               List<ClientUser> listUser=
      
        new
      
       ArrayList<ClientUser>
      
        ();


      
      
        169
      
      
        for
      
      (
      
        int
      
       i=0;i<result.size();i++
      
        ){


      
      
        170
      
      
                    listUser.add(Constants.json2ClientUser((String)result.get(i)));


      
      
        171
      
      
                }


      
      
        172
      
               Collections.sort(listUser,
      
        new
      
       Comparator<ClientUser>
      
        (){


      
      
        173
      
      
        public
      
      
        int
      
      
         compare(ClientUser o1, ClientUser o2) {


      
      
        174
      
      
        return
      
      
         o2.getLastLoginTime().compareTo(o1.getLastLoginTime());


      
      
        175
      
      
                    }


      
      
        176
      
      
                });


      
      
        177
      
               onlines=
      
        listUser;


      
      
        178
      
      
        int
      
       start = (page - 1) *
      
         pageSize;


      
      
        179
      
      
        int
      
       toIndex=(start+pageSize)>onlines.size()?onlines.size():start+
      
        pageSize;


      
      
        180
      
               List list =
      
         onlines.subList(start, toIndex);


      
      
        181
      
      
        return
      
      
         list;


      
      
        182
      
      
            }


      
      
        183
      
      
        private
      
      
        static
      
      
         String getKey(Object obj){


      
      
        184
      
               String temp =
      
         String.valueOf(obj);


      
      
        185
      
               String key[] = temp.split(":"
      
        );


      
      
        186
      
      
        return
      
       SID_PREFIX+key[key.length-1
      
        ];


      
      
        187
      
      
            }


      
      
        188
      
      
        /**
      
      
        189
      
      
             * 


      
      
        190
      
      
             * @Title: onlineCount


      
      
        191
      
      
             * @Description: 總在線人數


      
      
        192
      
      
             * 
      
      
        @param
      
      
        @return
      
      
        193
      
      
             * 
      
      
        @return
      
      
         int


      
      
        194
      
      
             * 
      
      
        @throws
      
      
        195
      
      
        */
      
      
        196
      
      
        public
      
      
        static
      
      
        int
      
      
         onlineCount(){


      
      
        197
      
               Jedis jedis =
      
         RedisPoolUtils.getJedis();


      
      
        198
      
               Set online = jedis.keys(SID_PREFIX+"*"
      
        );


      
      
        199
      
      
                RedisPoolUtils.release(jedis);


      
      
        200
      
      
        return
      
      
         online.size();


      
      
        201
      
      
            }


      
      
        202
      
      
        /**
      
      
        203
      
      
             * 獲取指定頁面在線人數總數


      
      
        204
      
      
        */
      
      
        205
      
      
        public
      
      
        static
      
      
        int
      
      
         broadcastCount(String identify) {


      
      
        206
      
               Jedis jedis =
      
         RedisPoolUtils.getJedis();


      
      
        207
      
               Set online = jedis.keys(VID_PREFIX+identify+":*"
      
        );


      
      
        208
      
      
                RedisPoolUtils.release(jedis);


      
      
        209
      
      
        return
      
      
         online.size();


      
      
        210
      
      
            }


      
      
        211
      
      
        /**
      
      
        212
      
      
             * 自己是否在線


      
      
        213
      
      
        */
      
      
        214
      
      
        public
      
      
        static
      
      
        boolean
      
      
         broadcastIsOnline(String identify,String uid) {


      
      
        215
      
               Jedis jedis =
      
         RedisPoolUtils.getJedis();


      
      
        216
      
               String online = jedis.get(VID_PREFIX+identify+":"+
      
        uid);


      
      
        217
      
      
                RedisPoolUtils.release(jedis);


      
      
        218
      
      
        return
      
       !StringUtil.isBlank(online);
      
        //
      
      
        不為空就代表已經找到數據了,也就是上線了
      
      
        219
      
      
            }


      
      
        220
      
      
        /**
      
      
        221
      
      
             * 獲取指定頁面在線人數總數


      
      
        222
      
      
        */
      
      
        223
      
      
        public
      
      
        static
      
      
        int
      
      
         broadcastCount() {


      
      
        224
      
               Jedis jedis =
      
         RedisPoolUtils.getJedis();


      
      
        225
      
               Set online = jedis.keys(VID_PREFIX+"*"
      
        );


      
      
        226
      
      
                RedisPoolUtils.release(jedis);


      
      
        227
      
      
        return
      
      
         online.size();


      
      
        228
      
      
            }


      
      
        229
      
      
        /**
      
      
        230
      
      
             * 


      
      
        231
      
      
             * @Title: isOnline


      
      
        232
      
      
             * @Description: 指定賬號是否登陸


      
      
        233
      
      
             * 
      
      
        @param
      
      
        @param
      
      
         sessionId


      
      
        234
      
      
             * 
      
      
        @param
      
      
        @return
      
      
        235
      
      
             * 
      
      
        @return
      
      
         boolean 


      
      
        236
      
      
             * 
      
      
        @throws
      
      
        237
      
      
        */
      
      
        238
      
      
        public
      
      
        static
      
      
        boolean
      
      
         isOnline(String uid){


      
      
        239
      
               Jedis jedis =
      
         RedisPoolUtils.getJedis();


      
      
        240
      
      
        boolean
      
       isLogin = jedis.exists(UID_PREFIX+
      
        uid);


      
      
        241
      
      
                RedisPoolUtils.release(jedis);


      
      
        242
      
      
        return
      
      
         isLogin;


      
      
        243
      
      
            }


      
      
        244
      
      
        public
      
      
        static
      
      
        boolean
      
      
         isOnline(String uid,String sid){


      
      
        245
      
               Jedis jedis =
      
         RedisPoolUtils.getJedis();


      
      
        246
      
               String loginSid = jedis.get(UID_PREFIX+
      
        uid);


      
      
        247
      
      
                RedisPoolUtils.release(jedis);


      
      
        248
      
      
        return
      
      
         sid.equals(loginSid);


      
      
        249
      
      
            }


      
      
        250
      
       }
    

  由于在線狀態是記錄在Redis中的,并不單純依靠Session的過期機制來實現,所以需要通過攔截器在每次發送請求的時候去更新Redis中相應的緩存過期時間來更新用戶的在線狀態。

登陸、退出操作與單機版相似,強制下線需要配合攔截器實現,當用戶下次訪問的時候,自己來校驗自己的狀態是否為已經下線,不再由服務器控制。

配合攔截器實現在線狀態維持與強制登陸(使其他地方登陸了該賬戶的用戶下線)功能:

      
         1
      
      
          ...


      
      
         2
      
      
        if
      
      (uid != 
      
        null
      
      ){
      
        //
      
      
        已登錄
      
      
         3
      
      
        if
      
      (!
      
        OnlineUtils.isOnline(uid, session.getId())){


      
      
         4
      
      
                    session.invalidate();


      
      
         5
      
      
        return
      
      
         ai.invoke();


      
      
         6
      
               }
      
        else
      
      
        {


      
      
         7
      
                   OnlineUtils.login(session.getId(), (ClientUser)session.getAttribute("clientUser"
      
        ));


      
      
         8
      
      
        //
      
      
        刷新緩存
      
      
         9
      
      
                }


      
      
        10
      
      
            }


      
      
        11
      
           ...
    

注:Redis在線列表工具類中的部分代碼是后來需要實現限制同時訪問指定頁面瀏覽人數功能而添加的,同樣基于Redis實現,前端由Ajax輪詢來更新用戶停留頁面的狀態。

附錄:

Redis連接池配置文件:

      ###redis##config########

#redis服務器ip # 

#redis.ip=
      
        localhost


      
      #redis服務器端口號#
      
        

redis
      
      .port=6379

###jedis##pool##config###

#jedis的最大分配對象#
      
        

jedis
      
      .pool.maxActive=1024

#jedis最大保存idel狀態對象數 #
      
        

jedis
      
      .pool.maxIdle=200

#jedis池沒有對象返回時,最大等待時間 #
      
        

jedis
      
      .pool.
      
        maxWait
      
      =1000

#jedis調用borrowObject方法時,是否進行有效檢查#
      
        

jedis
      
      .pool.testOnBorrow=
      
        true


      
      #jedis調用returnObject方法時,是否進行有效檢查 #
      
        

jedis
      
      .pool.testOnReturn=true
    

?

基于Redis的在線用戶列表解決方案


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 国产一区亚洲欧美成人 | 久久精品vr中文字幕 | 久久国产精品免费看 | 老子影院午夜理伦手机不卡 | 国产精品青青青高清在线密亚 | 欧美午夜大片 | 狠狠干奇米 | 一区二区三区无码高清视频 | 亚洲最新在线视频 | 欧美日韩中文在线视频 | 99久久99久久久精品久久 | 久久精品2 | 久草国产在线播放 | 天天干夜夜做 | 老头老太做爰xxxx视频 | 黄色免费在线观看 | 久久中文字幕日韩精品 | 亚洲a成人7777777久久 | 国产成人亚洲精品一区二区在线看 | 黑人巨大vs日本妞 | 九九爱这里只有精品 | 久久这里只有精品免费的 | 狠狠操天天操夜夜操 | 婷婷 色天使 | 奇米欧美成人综合影院 | 亚洲图片 中文字幕 | 九九黄色大片 | 狠狠操天天操夜夜操 | 免费a级毛片在线播放 | 久久社区 | 一区二区三区不卡在线 | 香蕉视频黄网站 | 一级毛片免费视频观看 | 亚洲国产精品乱码一区二区三区 | 狠狠色噜噜狠狠狠97影音先锋 | 久久亚洲精品一区成人 | 99久久亚洲精品影院 | 欧美成人欧美激情欧美风情 | 欧美特黄一级大黄录像 | 欧美又粗又硬 | 亚洲精品国产第一区二区尤物 |