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;
    }
    
    
    
    
}

 

 

posted @ 2013-01-20 03:11  zhong320  阅读(493)  评论(0)    收藏  举报