基於Redis的線上使用者列表解決方案
阿新 • • 發佈:2019-01-04
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 }