web在线用户状态
思路:
用一个单列对象存储在线用户列表。
前端定时请求服务器。服务器更新用户状态
服务器定时检查用户状态,超过X分钟没更新的用户,则移除出在线列表。
以下是代码:
在线列表操作
按照每100个用户为一组分组。减少查询开销
package com.sw.vo.sy; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.springframework.util.Assert; import com.sw.tool.Struts2Utils; public class EmplList { public static final int LIST_MAX_SIZE = 100; public static final int INIT = 1; public static final int TIME_OUT = 6 * 60; // 应该和服务器周期相同 private static int mapIndex = INIT; private static final Map<Integer, List<EmplInfo>> emplMap = new HashMap<Integer, List<EmplInfo>>(); private static EmplList emplList = new EmplList(); private EmplList() { } public static EmplList getInstance() { return emplList; } /** * 添加一个在线用户 * * @param e */ private synchronized void add(EmplInfo e) { List<EmplInfo> l = getList(); e.mapIndex = mapIndex; e.listIndex = l.size() + 1; l.add(e); } public void addUser(EmplInfo e) { EmplInfo e2 = getUserByID(e.emplId,e.ip); if(e2!=null){ e2.sessionId = e.sessionId; }else{ add(e); } } /** * 对比IP和ID,查找ID,IP都相等的用户, * 如果查找出多个,则去除第一个之后的所有。 * @param id * @param ip * @return */ private EmplInfo getUserByID(String id, String ip) { EmplInfo e2 = null; if (id == null || ip == null) return e2; boolean b = true; for (List<EmplInfo> l : emplMap.values()) { Iterator<EmplInfo> el2 = l.iterator(); while (el2.hasNext()) { EmplInfo e = el2.next(); if (id.equals(e.emplId) && ip.equals(e.ip)) { if (b) { e2 = e; b = false; } else { el2.remove(); } } } } return e2; } /** * 根据分组号,和sessionid获取用户 * * @author zhong * @param i * @param sid * @return */ public EmplInfo getUserBySID(Integer i, String sid) { List<EmplInfo> list = emplMap.get(i); for (EmplInfo e : list) { if (e.sessionId == sid) return e; } return null; } /** * 根据索引值查找用户 * * @param mapIndex * @param ListIndex * @return */ private EmplInfo getUserByIndex(Integer mapIndex, Integer ListIndex) { EmplInfo e = null; try { e = emplMap.get(mapIndex).get(ListIndex); } catch (Exception e2) { return null; } return Struts2Utils.getSession().getId() == e.sessionId ? e : null; } /** * 更新用户状态 * * @author zhong * @param e */ public void update(EmplInfo e) { EmplInfo e2 = getUserByIndex(e.mapIndex, e.listIndex); if (e2 != null) e2.date = new Date(); } /** * 检查用户状态,并且移除超时用户 * * @author zhong */ public void checkStatus() { Date time = new Date(); for (Map.Entry e : emplMap.entrySet()) { List<EmplInfo> el = (List<EmplInfo>) e.getValue(); Iterator<EmplInfo> el2 = el.iterator(); while (el2.hasNext()) { EmplInfo e2 = el2.next(); if (time.getTime() - e2.date.getTime() > TIME_OUT * 1000) { el2.remove(); } } } } /** * 移除一个用户 * * @author zhong * @param e */ public void reMove(EmplInfo e) { List<EmplInfo> l = emplMap.get(e.mapIndex); EmplInfo e1 = l.get(e.listIndex); if (e.sessionId.equals(e1.sessionId) && e.emplId.equals(e1.emplId)) { l.remove(e.listIndex); } } /** * 获取一组list,如果超出组边界,就创建一个新组 * * @author zhong * @return */ private List<EmplInfo> getList() { int i = 1; // 用于记录mapIndex。给add方法使用 for (List<EmplInfo> l : emplMap.values()) { if (l.size() < LIST_MAX_SIZE) return l; i++; } mapIndex = i; List<EmplInfo> l2 = new ArrayList<EmplInfo>(); emplMap.put(i, l2); return l2; } public int getMaxMapIndex() { return emplMap.size(); } /** * 测试方法,不建议使用,仅用来看值 * @return */ public Map<Integer, List<EmplInfo>> getMap(){ return emplMap; } }
用户信息:
package com.sw.vo.sy; import java.util.Date; public class EmplInfo { public String sessionId = ""; public String emplId = ""; public String name = ""; public String loginame = ""; public String ip = ""; public Date date = new Date(); public Integer mapIndex; public Integer listIndex; /** * get/set 为jackson序列化对象所用 * @return */ public String getSessionId() { return sessionId; } public void setSessionId(String sessionId) { this.sessionId = sessionId; } public String getEmplId() { return emplId; } public void setEmplId(String emplId) { this.emplId = emplId; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getLoginame() { return loginame; } public void setLoginame(String loginame) { this.loginame = loginame; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public Integer getMapIndex() { return mapIndex; } public void setMapIndex(Integer mapIndex) { this.mapIndex = mapIndex; } public Integer getListIndex() { return listIndex; } public void setListIndex(Integer listIndex) { this.listIndex = listIndex; } public String getIp() { return ip; } public void setIp(String ip) { this.ip = ip; } }

浙公网安备 33010602011771号