Skip to content

3:Session

gris.wang edited this page Nov 8, 2017 · 1 revision

Session管理

实现了自定义的Session管理,Session是基于Netty的ChannelHandlerContext(以下简称context)实现的,使用context中通道的channelId作为sessionId。每个session使用一个map来存储需要保存的属性值。

HttpSession
/**
 * HttpSession
 * @author gris.wang
 * @since 2017/11/6
 */
public class HttpSession {

    /**
     * 会话id
     */
    private ChannelId id;

    /**
     * 会话保存的ChannelHandlerContext
     */
    private ChannelHandlerContext context;

    /**
     * 创建时间
     */
    private Long createTime;

    /**
     * 过期时间
     * 每次请求时都更新过期时间
     */
    private Long expireTime;

    /**
     * Session中存储的数据
     */
    private Map<String,Object> sessionMap;

    private void assertSessionMapNotNull(){
        if(sessionMap==null){
            sessionMap= new HashMap<String,Object>();
        }
    }


    private HttpSession(){

    }


    //=====================================


    public HttpSession(ChannelHandlerContext context){
        this(context.channel().id(),context);
    }

    public HttpSession(ChannelId id,ChannelHandlerContext context){
        this(id,context,System.currentTimeMillis());
    }

    public HttpSession(ChannelId id,ChannelHandlerContext context,Long createTime){
        this(id,context,createTime,createTime + SessionConfig.instance().sessionTimeOut());
    }

    public HttpSession(ChannelId id,ChannelHandlerContext context,Long createTime,Long expireTime){
        this.id = id;
        this.context = context;
        this.createTime = createTime;
        this.expireTime = expireTime;
        assertSessionMapNotNull();
    }

    public getXXX(){}

    public setXXX(){}
    
    /**
     * 是否过期
     * @return
     */
    public boolean isExpire(){
        return this.expireTime>=System.currentTimeMillis();
    }

    /**
     * 设置attribute
     * @param key
     * @param val
     */
    public void setAttribute(String key,Object val){
        sessionMap.put(key,val);
    }

    /**
     * 获取key的值
     * @param key
     */
    public void getAttribute(String key){
        sessionMap.get(key);
    }

    /**
     * 是否存在key
     * @param key
     */
    public boolean containsAttribute(String key){
        return sessionMap.containsKey(key);
    }
}
SessionHelper
/**
 * Session辅助器
 * @author gris.wang
 * @since 2017/11/6
 */
public class SessionHelper {

    /**
     * 保存session对象的map
     */
    private Map<ChannelId,HttpSession> sessionMap;

    private static SessionHelper manager;

    private SessionHelper(){

    }


    //======================================


    /**
     * 获取单例
     * @return
     */
    public static SessionHelper instange(){
        synchronized (SessionHelper.class) {
            if (manager == null) {
                manager = new SessionHelper();
                if (manager.sessionMap == null) {
                    // 需要线程安全的Map
                    manager.sessionMap = new ConcurrentHashMap<ChannelId,HttpSession>();
                }
            }
        }
        return manager;
    }

    /**
     * 判断session是否存在
     * @param context
     * @return
     */
    public boolean containsSession(ChannelHandlerContext context){
        return context!=null && context.channel()!=null && context.channel().id()!=null && manager.sessionMap.get(context.channel().id())!=null;
    }

    /**
     * 添加一个session
     * @param context
     * @param session
     */
    public void addSession(ChannelHandlerContext context,HttpSession session){
        if(context==null || context.channel()==null || context.channel().id()==null || session==null){
            throw new InvalidSessionException("context or session is null");
        }
        manager.sessionMap.put(context.channel().id(),session);
    }

    /**
     * 获取一个session
     * @param context
     * @return
     */
    public HttpSession getSession(ChannelHandlerContext context){
        if(context==null || context.channel()==null || context.channel().id()==null){
            throw new InvalidSessionException("context is null");
        }
        return manager.sessionMap.get(context.channel().id());
    }

    /**
     * 获取一个session,获取不到时自动创建一个
     * @param context
     * @param createIfNull
     * @return
     */
    public HttpSession getSession(ChannelHandlerContext context,boolean createIfNull){
        HttpSession session = getSession(context);
        if(session==null && createIfNull){
            session = new HttpSession(context);
            manager.sessionMap.put(context.channel().id(),session);
        }
        return session;
    }

    /**
     * 清除过期的session
     * 需要在定时器中执行该方法
     */
    public void clearExpireSession(){
        Iterator<Map.Entry<ChannelId,HttpSession>> iterator = manager.sessionMap.entrySet().iterator();
        while(iterator.hasNext()){
            Map.Entry<ChannelId,HttpSession> sessionEntry = iterator.next();
            if(sessionEntry.getValue()==null || sessionEntry.getValue().isExpire()){
                iterator.remove();
            }
        }
    }

}
SessionManager
/**
 * Session管理器
 * @author gris.wang
 * @since 2017/11/6
 */
public class SessionManager {

    private SessionManager(){

    }


    //======================================

    /**
     * 判断session是否存在
     * @return
     */
    public static boolean containsSession(){
        ChannelHandlerContext context = (ChannelHandlerContext)DataHolder.get(DataHolder.HolderType.CONTEXT);
        return SessionHelper.instange().containsSession(context);
    }

    /**
     * 添加一个session
     * @param session
     */
    public static void addSession(HttpSession session){
        ChannelHandlerContext context = (ChannelHandlerContext)DataHolder.get(DataHolder.HolderType.CONTEXT);
        SessionHelper.instange().addSession(context, session);
    }

    /**
     * 获取一个session
     * @return
     */
    public static HttpSession getSession(){
        ChannelHandlerContext context = (ChannelHandlerContext)DataHolder.get(DataHolder.HolderType.CONTEXT);
        return SessionHelper.instange().getSession(context);
    }

    /**
     * 获取一个session,获取不到时自动创建一个
     * @param createIfNull
     * @return
     */
    public static HttpSession getSession(boolean createIfNull){
        ChannelHandlerContext context = (ChannelHandlerContext)DataHolder.get(DataHolder.HolderType.CONTEXT);
        return SessionHelper.instange().getSession(context,createIfNull);
    }

    /**
     * 清除过期的session
     * 需要在定时器中执行该方法
     */
    public static void clearExpireSession(){
        SessionHelper.instange().clearExpireSession();
    }

}
Clone this wiki locally