1. 程式人生 > >基於Redis的線上使用者列表解決方案

基於Redis的線上使用者列表解決方案

1 import java.util.ArrayList; 2 import java.util.Collections; 3 import java.util.Comparator; 4 import java.util.Date; 5 import java.util.List; 6 import java.util.Set; 7 8 import net.sf.json.JSONObject; 9 import net.sf.json.JsonConfig; 10 import net.sf.json.processors.JsonValueProcessor;
11 12 import cn.sccl.common.util.StringUtil; 13 14 import com.xxx.common.util.JsonDateValueProcessor; 15 import com.xxx.user.model.ClientUser; 16 17 import redis.clients.jedis.Jedis; 18 import redis.clients.jedis.Pipeline; 19 import tools.Constants; 20 21 /** 22 * 23 * Redis快取中存放兩組key:
24 * 1.SID_PREFIX開頭,存放登陸使用者的SessionId與ClientUser的Json資料 25 * 2.UID_PREFIX開頭,存放登入使用者的UID與SessionId對於的資料 26 * 27 * 3.VID_PREFIX開頭,存放位於指定頁面使用者的資料(與Ajax一起使用,用於實現指定頁面同時瀏覽人數的限制功能) 28 * 29 * @ClassName: OnlineUtils 30 * @Description: 線上列表操作工具類 31 * @author BuilderQiu 32 * @date 2014-1-9 上午09:25:43
33 * 34 */ 35 public class OnlineUtils { 36 37 //KEY值根據SessionID生成 38 private static final String SID_PREFIX = "online:sid:"; 39 private static final String UID_PREFIX = "online:uid:"; 40 private static final String VID_PREFIX = "online:vid:"; 41 private static final int OVERDATETIME = 30 * 60; 42 private static final int BROADCAST_OVERDATETIME = 70;//Ajax每60秒發起一次,超過BROADCAST_OVERDATETIME時間長度未發起表示已經離開該頁面 43 44 public static void login(String sid,ClientUser user){ 45 46 Jedis jedis = RedisPoolUtils.getJedis(); 47 48 jedis.setex(SID_PREFIX+sid, OVERDATETIME, userToString(user)); 49 jedis.setex(UID_PREFIX+user.getId(), OVERDATETIME, sid); 50 51 RedisPoolUtils.release(jedis); 52 } 53 54 public static void broadcast(String uid,String identify){ 55 56 if(uid==null||"".equals(uid)) //異常資料,正常情況下登陸使用者才會發起該請求 57 return ; 58 59 Jedis jedis = RedisPoolUtils.getJedis(); 60 61 jedis.setex(VID_PREFIX+identify+":"+uid, BROADCAST_OVERDATETIME, uid); 62 63 RedisPoolUtils.release(jedis); 64 } 65 66 67 private static String userToString(ClientUser user){ 68 JsonConfig config = new JsonConfig(); 69 JsonValueProcessor processor = new JsonDateValueProcessor("yyyy-MM-dd HH:mm:ss"); 70 config.registerJsonValueProcessor(Date.class, processor); 71 JSONObject obj = JSONObject.fromObject(user, config); 72 73 return obj.toString(); 74 } 75 76 /** 77 * 78 * @Title: logout 79 * @Description: 退出 80 * @param @param sessionId 81 * @return void 82 * @throws 83 */ 84 public static void logout(String sid,String uid){ 85 86 Jedis jedis = RedisPoolUtils.getJedis(); 87 88 jedis.del(SID_PREFIX+sid); 89 jedis.del(UID_PREFIX+uid); 90 91 RedisPoolUtils.release(jedis); 92 } 93 94 /** 95 * 96 * @Title: logout 97 * @Description: 退出 98 * @param @param UserId 使指定使用者下線 99 * @return void 100 * @throws 101 */ 102 public static void logout(String uid){ 103 Jedis jedis = RedisPoolUtils.getJedis(); 104 105 //刪除sid 106 jedis.del(SID_PREFIX+jedis.get(UID_PREFIX+uid)); 107 //刪除uid 108 jedis.del(UID_PREFIX+uid); 109 110 RedisPoolUtils.release(jedis); 111 } 112 113 public static String getClientUserBySessionId(String sid){ 114 115 Jedis jedis = RedisPoolUtils.getJedis(); 116 117 String user = jedis.get(SID_PREFIX+sid); 118 119 RedisPoolUtils.release(jedis); 120 121 return user; 122 } 123 124 public static String getClientUserByUid(String uid){ 125 Jedis jedis = RedisPoolUtils.getJedis(); 126 127 String user = jedis.get(SID_PREFIX+jedis.get(UID_PREFIX+uid)); 128 129 RedisPoolUtils.release(jedis); 130 131 return user; 132 } 133 134 /** 135 * 136 * @Title: online 137 * @Description: 所有的key 138 * @return List 139 * @throws 140 */ 141 public static List online(){ 142 143 Jedis jedis = RedisPoolUtils.getJedis(); 144 145 Set online = jedis.keys(SID_PREFIX+"*"); 146 147 RedisPoolUtils.release(jedis); 148 return new ArrayList(online); 149 } 150 151 /** 152 * 153 * @Title: online 154 * @Description: 分頁顯示線上列表 155 * @return List 156 * @throws 157 */ 158 public static List onlineByPage(int page,int pageSize) throws Exception{ 159 160 Jedis jedis = RedisPoolUtils.getJedis(); 161 162 Set onlineSet = jedis.keys(SID_PREFIX+"*"); 163 164 165 List onlines =new ArrayList(onlineSet); 166 167 if(onlines.size() == 0){ 168 return null; 169 } 170 171 Pipeline pip = jedis.pipelined(); 172 for(Object key:onlines){ 173 pip.get(getKey(key)); 174 } 175 List result = pip.syncAndReturnAll(); 176 RedisPoolUtils.release(jedis); 177 178 List<ClientUser> listUser=new ArrayList<ClientUser>(); 179 for(int i=0;i<result.size();i++){ 180 listUser.add(Constants.json2ClientUser((String)result.get(i))); 181 } 182 Collections.sort(listUser,new Comparator<ClientUser>(){ 183 public int compare(ClientUser o1, ClientUser o2) { 184 return o2.getLastLoginTime().compareTo(o1.getLastLoginTime()); 185 } 186 }); 187 onlines=listUser; 188 int start = (page - 1) * pageSize; 189 int toIndex=(start+pageSize)>onlines.size()?onlines.size():start+pageSize; 190 List list = onlines.subList(start, toIndex); 191 192 return list; 193 } 194 195 private static String getKey(Object obj){ 196 197 String temp = String.valueOf(obj); 198 String key[] = temp.split(":"); 199 200 return SID_PREFIX+key[key.length-1]; 201 } 202 203 /** 204 * 205 * @Title: onlineCount 206 * @Description: 總線上人數 207 * @param @return 208 * @return int 209 * @throws 210 */ 211 public static int onlineCount(){ 212 213 Jedis jedis = RedisPoolUtils.getJedis(); 214 215 Set online = jedis.keys(SID_PREFIX+"*"); 216 217 RedisPoolUtils.release(jedis); 218 219 return online.size(); 220 221 } 222 223 /** 224 * 獲取指定頁面線上人數總數 225 */ 226 public static int broadcastCount(String identify) { 227 Jedis jedis = RedisPoolUtils.getJedis(); 228 229 Set online = jedis.keys(VID_PREFIX+identify+":*"); 230 231 232 233 RedisPoolUtils.release(jedis); 234 235 return online.size(); 236 } 237 238 /** 239 * 自己是否線上 240 */ 241 public static boolean broadcastIsOnline(String identify,String uid) { 242 243 Jedis jedis = RedisPoolUtils.getJedis(); 244 245 String online = jedis.get(VID_PREFIX+identify+":"+uid); 246 247 RedisPoolUtils.release(jedis); 248 249 return !StringUtil.isBlank(online);//不為空就代表已經找到資料了,也就是上線了 250 } 251 252 /** 253 * 獲取指定頁面線上人數總數 254 */ 255 public static int broadcastCount() { 256 Jedis jedis = RedisPoolUtils.getJedis(); 257 258 Set online = jedis.keys(VID_PREFIX+"*"); 259 260 RedisPoolUtils.release(jedis); 261 262 return online.size(); 263 } 264 265 266 /** 267 * 268 * @Title: isOnline 269 * @Description: 指定賬號是否登陸 270 * @param @param sessionId 271 * @param @return 272 * @return boolean 273 * @throws 274 */ 275 public static boolean isOnline(String uid){ 276 277 Jedis jedis = RedisPoolUtils.getJedis(); 278 279 boolean isLogin = jedis.exists(UID_PREFIX+uid); 280 281 RedisPoolUtils.release(jedis); 282 283 return isLogin; 284 } 285 286 public static boolean isOnline(String uid,String sid){ 287 288 Jedis jedis = RedisPoolUtils.getJedis(); 289 290 String loginSid = jedis.get(UID_PREFIX+uid); 291 292 RedisPoolUtils.release(jedis); 293 294 return sid.equals(loginSid); 295 } 296 }