在线登录用户统计

        在线登录用户统计只统计登录后的在线用户,忽略未登录的用户,并且同一帐号不允许多次登录,即当用户登录时,如果该用户帐号已经在其他地方登录,则自动踢出之前登录的用户。登录标识为Session中logonUserView属性是否为null。实现原理:借助HttpSessionAttributeListener和HttpSessionListener来实现。用户登录时,如果密码验证通过,则判断改用户是否已经登录,如果已经登录则将之前登录的用户强制注销,然后将记录这用户信息的LogonUserView对象放入当前session,这时候HttpSessionAttributeListener的attributeAdded事件被触发,该用户被记录到在线用户列表。用户注销时或Session自动失效时,会触发HttpSessionListener的sessionDestroyed事件,从在线用户列表中移除注销用户。具体实现代码如下:

1. LogonUserView类,记录登录后用户信息

public class LogonUserView implements java.io.Serializable {
    private String userid;
    private String userName;
    // 省略其他属性和get、set方法
}
2. OnlineUserView类,记录在线用户信息

public class OnlineUserView {
    private String userId;
    private String userName;
    private String loginIP;
    // 在线用户对应Session,踢用户时使用
    private HttpSession userSession;
    // 省略其他属性和get、set方法
}
3. 登录方法(片段)

// 检测是否是在不同浏览器下已有相同用户Id的用户登陆
List onlineUsers = OnlineUserListener.getOnlineUsers();
for(int i = 0; i < onlineUsers.size(); i++){
    // 在线用户视图
    OnlineUserView onlineUserView = (OnlineUserView)onlineUsers.get(i);
    // 在线用户Session
    HttpSession onlineUserSession = onlineUserView.getUserSession();
    // 同一用户
    if(authorizedUserId.equals(onlineUserView.getUserId())){
        // 在不同机器上登陆,提示,否则不提示
        if(!request.getRemoteAddr().equals(onlineUserView.getLoginIP())){
            // 提示信息
        }
        try{
            if(!onlineUserSession.getId().equals(request.getSession().getId())){
                // 强制注销之前登陆用户,并将该用户从在线用户列表删除
                onlineUserSession.invalidate();
            }
        }catch(IllegalStateException ise){}
        break;
    }    
}
                
// 绑定登陆用户信息到Session,监听器自动将该用户添加到在线用户列表
request.getSession().setAttribute("logonUserView", logonUserView);
4. 注销方法(片段)

// 使session失效,触发sessionDestroyed事件,从在线用户列表中移除注销用户
session.invalidate();
5. 在线用户监听器

public class OnlineUserListener implements HttpSessionAttributeListener, HttpSessionListener {
    
    /**
     * 在线用户列表
     */
    private static List onlineUsers = new ArrayList();
    
    /**
     * 获取在线用户列表
     * @return
     */
    public static List getOnlineUsers(){
        return onlineUsers;
    }

    /* 
     * session 属性添加时(即首次执行setAttribute时)触发
     */
    public void attributeAdded(HttpSessionBindingEvent event) {
        if(event.getSession()==null){
            return;
        }
        // 当执行setAttribute("logonUserView",logonUserView)时
        // 将当前用户添加到在线用户列表中
        if(event.getName().equalsIgnoreCase("logonUserView")){
            // 获取当前登陆用户信息及session
            LogonUserView user = (LogonUserView)event.getValue();
            HttpSession session = event.getSession();
            
            // 创建在线用户信息对象
            OnlineUserView onlineUserView = new OnlineUserView();
            onlineUserView.setLoginIP(user.getLoginIP());
            onlineUserView.setUserId(user.getUserfullid());
            onlineUserView.setUserName(user.getUsername());
            onlineUserView.setUserSession(session);
            
            // 添加到在线用户列表
            onlineUsers.add(onlineUserView);
        }
    }

    /* 
     * session 属性移除时(即执行removeAttribute时)触发
     */
    public void attributeRemoved(HttpSessionBindingEvent event) {
    }

    /* 
     * session 属性更新时(即再次执行setAttribute时)触发
     */
    public void attributeReplaced(HttpSessionBindingEvent event) {
        if(event.getSession()==null){
            return;
        }

        // 当执行再次执行setAttribute("logonUserView")时,发生用户替换
        if(event.getName().equalsIgnoreCase("logonUserView")){
            // 获取被替换用户信息及session
            LogonUserView user = (LogonUserView)event.getValue();
            // 更新在线用户信息
            HttpSession session = event.getSession();
            // 获取当前登陆用户信息
            LogonUserView newUser = (LogonUserView)session.getAttribute("logonUserView");
            // 循环查找被替换用户在线信息
            for(int i=0;i<onlineUsers.size();i++){
                OnlineUserView onlineUserView = (OnlineUserView)onlineUsers.get(i);
                if(onlineUserView.getUserId().equals(user.getUserfullid())){
                    // 更新在线用户信息
                    onlineUserView.setLoginIP(newUser.getLoginIP());
                    onlineUserView.setUserId(newUser.getUserfullid());
                    onlineUserView.setUserName(newUser.getUsername());                    
                    break;
                }
            }
        }
    }

    /* 
     * session 创建时触发
     */
    public void sessionCreated(HttpSessionEvent event) {
    }

    /* 
     * session 销毁时(即用户注销、session超时时)触发
     */
    public void sessionDestroyed(HttpSessionEvent event) {
        if(event.getSession()==null){
            System.out.println("OnlineUserListener.sessionDestroyed() session==null");
            return;
        }
        // 获取当前登陆用户信息及session
        HttpSession session = event.getSession();
        for(int i=0; i<onlineUsers.size();i++){
            OnlineUserView onlineUserView = (OnlineUserView)onlineUsers.get(i);
            if(onlineUserView!=null && onlineUserView.getUserSession()!=null && session!=null 
                && onlineUserView.getUserSession().getId().equals(session.getId())){
                // 从在线用户列表移除用户
                onlineUsers.remove(onlineUserView);
                break;
            }
        }
    }
}
说明:
该统计方法在集群环境下无法使用,集群环境可以将在线用户信息存入数据库,各服务器连接统一数据库


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值