fs-danaus
2023-07-10 4849078e3450b8d3b3030a658a34dd58b0630fc5
src/com/yc/listener/SessionListener.java
@@ -1,36 +1,5 @@
package com.yc.listener;
import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import com.alibaba.fastjson.JSON;
import com.yc.sdk.WebSocketMessage.action.WebSocketMessageServer;
import com.yc.sdk.WebSocketMessage.entity.MessageInfo;
import com.yc.sdk.WebSocketMessage.entity.MessageType;
import com.yc.sdk.shopping.action.api.InvitationCode;
import org.apache.catalina.Manager;
import org.apache.catalina.Session;
import org.apache.catalina.core.ApplicationContext;
import org.apache.catalina.core.ApplicationContextFacade;
import org.apache.catalina.core.StandardContext;
import com.yc.action.mail.service.OtherMailIfc;
import com.yc.entity.DataSourceEntity;
import com.yc.entity.OnlineUserEntity;
@@ -38,9 +7,37 @@
import com.yc.license.InitLicense;
import com.yc.multiData.MultiDataSource;
import com.yc.multiData.SpObserver;
import com.yc.sdk.WebSocketMessage.action.WebSocketMessageServer;
import com.yc.sdk.WebSocketMessage.entity.MessageInfo;
import com.yc.sdk.WebSocketMessage.entity.MessageType;
import com.yc.sdk.shopping.action.api.InvitationCode;
import com.yc.service.user.UserAccountServiceIfc;
import com.yc.utils.FileUtil;
import com.yc.utils.SessionKey;
import org.apache.catalina.Manager;
import org.apache.catalina.Session;
import org.apache.catalina.core.ApplicationContext;
import org.apache.catalina.core.ApplicationContextFacade;
import org.apache.catalina.core.StandardContext;
import org.apache.commons.io.FileUtils;
import org.springframework.data.redis.core.RedisTemplate;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
 *  通过sessionId 获得session
@@ -49,17 +46,22 @@
 * @updatedBy
 * @updateTime 2011-5-16 下午01:57:00
 */
public class SessionListener implements HttpSessionListener,Serializable{
public class SessionListener implements HttpSessionListener, ServletContextListener,Serializable{
   private static final long serialVersionUID=762508508425279327l;
   private static Map<String,HttpSession> sessions = new ConcurrentHashMap<String,HttpSession>();   //所有会话信息
   private static  String servletContextPath;
    public static HttpSession getSession(String sessionId) {  
        if (sessionId == null) {  
            return null;  
        }  
        return sessions.get(sessionId);  
    }
    }
   @Override
   public void contextInitialized(ServletContextEvent sce) {
      servletContextPath=sce.getServletContext().getRealPath("/");
   }
   /**
    * 检查当前是否已超限制人数 , 返回:true 表示超过限制人数,false 未超过
    * @param dbid
@@ -173,28 +175,10 @@
            persistenceManager=standardContext.getManager();
         }
            return persistenceManager ;
        }
        catch(SecurityException e)
        {
           e.printStackTrace();
           // logger.error(e);
        }
        catch(NoSuchFieldException e)
        {
           e.printStackTrace();
           // logger.error(e);
        }
        catch(IllegalArgumentException e)
        {
           e.printStackTrace();
            //logger.error(e);
        }
        catch(IllegalAccessException e)
        {
           e.printStackTrace();
          //  logger.error(e);
        }
        return null ;
        }catch (Exception e){
         e.printStackTrace();
         return null;
      }
   }
   
   
@@ -289,6 +273,7 @@
   public static void delAllOnLineUser(String dbid) {
      try {
         Session[] sessions = getSessions( null) ;
         RedisTemplate redisTemplate = (RedisTemplate) FactoryBean.getBean("redisTemplate");
         for(Session session:sessions){
            HttpSession localSession=  session.getSession();
            String sessDbid = getDatabaseId(localSession ) ;   //获取会话 session 里面的 dbid
@@ -297,10 +282,42 @@
            }
            if(localSession!=null) {
               if (localSession.getAttribute(SessionKey.USER_LOGIN_TYPE).equals(SessionKey.USER_LOGIN_TYPE_APP)) {
                  RedisTemplate redisTemplate = (RedisTemplate) FactoryBean.getBean("redisTemplate");
                  //因为token只在app才有,所以才加上面的判断
                  redisTemplate.delete(InvitationCode.TOKEN_STR + localSession.getAttribute(SessionKey.DATA_BASE_ID) + ":" + localSession.getAttribute(SessionKey.USERCODE));
               }
               localSession.setAttribute("isClose",true);
               localSession.invalidate(); //删除该会话
            }
         }
      }catch (Exception e) {
         e.printStackTrace();
      }
   }
   /**
    * 删除所有登录端(pc,app)的用户信息
    * @param dbid
    * @return
    */
   public static void delAllOnLineUser(String dbid,String userCode) {
      try {
         Session[] sessions = getSessions( null) ;
         RedisTemplate redisTemplate = (RedisTemplate) FactoryBean.getBean("redisTemplate");
         for(Session session:sessions){
            HttpSession localSession=  session.getSession();
            String sessDbid = getDatabaseId(localSession ) ;   //获取会话 session 里面的 dbid
            if (sessDbid == null || !sessDbid.equals(dbid)) {
               continue ;
            }
            if(localSession!=null) {
               if(userCode.equalsIgnoreCase(localSession.getAttribute(SessionKey.USERCODE)+"")) {
                  //指定用户
                  if (localSession.getAttribute(SessionKey.USER_LOGIN_TYPE).equals(SessionKey.USER_LOGIN_TYPE_APP)) {
                     //因为token只在app才有,所以才加上面的判断
                     redisTemplate.delete(InvitationCode.TOKEN_STR + localSession.getAttribute(SessionKey.DATA_BASE_ID) + ":" + localSession.getAttribute(SessionKey.USERCODE));
                  }
                  localSession.setAttribute("isClose", true);
                  localSession.invalidate(); //删除该会话
               }
            }
         }
      }catch (Exception e) {
@@ -679,27 +696,41 @@
         HttpSession session = event.getSession();
         String sessionId = session.getId();
         String dbId = getDatabaseId(session) ;
         if(dbId!=null&&!"".equals(dbId)&&session.getAttribute("isClose")==null){//session.getAttribute("isClose")表示手动退出系统
            try{
               SpObserver.setDBtoInstance("_"+dbId);
               UserAccountServiceIfc userAccountServiceIfc = (UserAccountServiceIfc)FactoryBean.getBean("UserAccountServiceImpl");
               userAccountServiceIfc.doQuitLog(sessionId);   //更新 _sysloginlog 日志表
               //发送会话失效通知
               MessageInfo messageInfo = new MessageInfo();
               messageInfo.setDbId(Integer.parseInt(dbId));
               messageInfo.setMsgType(MessageType.RELOGIN_PAGE);
               messageInfo.setUserFromType(session.getAttribute(SessionKey.USER_LOGIN_TYPE)+"");
               messageInfo.setUserCode(session.getAttribute(SessionKey.USERCODE)+"");
               messageInfo.setSessionId(sessionId);
               messageInfo.setMsg("您已太长时间没有操作,请重新登录");
               WebSocketMessageServer.publishMessageToRedis(messageInfo);
            }catch (Exception e) {
               e.printStackTrace();
            }finally {
                SpObserver.setDBtoInstance();
         if(dbId!=null&&!"".equals(dbId)&&session.getAttribute("isClose")==null) {
            //----session.getAttribute("isClose")!=null表示手动退出系统,不需要发送通知
            //---增加下面处理是为了重启tomcat服务时不需要发送6017的消息,因为是主动关闭系统 by danaus 2023-06-27 14:56
            String reloadStatus = "reload=0";
            try {
               reloadStatus = FileUtils.readFileToString((new File(servletContextPath + "r.conf")), "UTF-8");
            } catch (FileNotFoundException e) {
               //没文件则新建
               FileUtil.writeFile("reload=0", servletContextPath + "r.conf");
            }
            if ("reload=0".equalsIgnoreCase(reloadStatus))
            {//reload=1表示是脚本重启tomcat服务,不需要发送通知
               try {
                  SpObserver.setDBtoInstance("_" + dbId);
                  UserAccountServiceIfc userAccountServiceIfc = (UserAccountServiceIfc) FactoryBean.getBean("UserAccountServiceImpl");
                  userAccountServiceIfc.doQuitLog(sessionId);   //更新 _sysloginlog 日志表
                  //发送会话失效通知
                  MessageInfo messageInfo = new MessageInfo();
                  messageInfo.setDbId(Integer.parseInt(dbId));
                  messageInfo.setMsgType(MessageType.RELOGIN_PAGE);
                  messageInfo.setUserFromType(session.getAttribute(SessionKey.USER_LOGIN_TYPE) + "");
                  messageInfo.setUserCode(session.getAttribute(SessionKey.USERCODE) + "");
                  messageInfo.setSessionId(sessionId);
                  messageInfo.setMsg("您已太长时间没有操作,请重新登录");
                  WebSocketMessageServer.publishMessageToRedis(messageInfo);
               } catch (Exception e) {
                  e.printStackTrace();
               } finally {
                  SpObserver.setDBtoInstance();
               }
            }
         }
         sessions.remove(sessionId);
      }catch(IOException e ) {
         e.printStackTrace();
      }catch(Exception e ) {
         e.printStackTrace();
         throw e ;
@@ -744,7 +775,7 @@
                  if (userCode == null || "".equals(userCode)) {
                     continue ;
                  }
                  session.setAttribute("isClose",true);
                  //先不删除会话信息,因再次使用时,会导致 Session already invalidated 错误,用 removeAllSessionKey 过程代替
                  session.invalidate();   //删除会话 ,