package com.dy.aceMw.server.forTcp; 
 | 
  
 | 
import java.net.InetAddress; 
 | 
import java.net.InetSocketAddress; 
 | 
import java.util.ArrayList; 
 | 
import java.util.HashMap; 
 | 
import java.util.Iterator; 
 | 
import java.util.List; 
 | 
import java.util.Map.Entry; 
 | 
  
 | 
import org.apache.mina.core.session.IoSession; 
 | 
  
 | 
import com.dy.aceMw.server.ServerProperties; 
 | 
  
 | 
  
 | 
public class TcpSessionCache { 
 | 
     
 | 
    /** 
 | 
     * 用Hashtable而不用HashMap原因: 
 | 
     * Hashtable线程安全的 
 | 
     * HashMap线程不安全的 
 | 
     * 多线程对sessionTable读出或存入,可能产生异常 
 | 
     * TcpSessionCache是在多线程环境下运行 
 | 
     * 
 | 
     * 2023-12-19实测,发现Hashtable并不线程安全,所以应用了HashMap和synchronized 
 | 
     */ 
 | 
    private static HashMap<String, TcpSession> sessionTable = new HashMap<String, TcpSession>() ; 
 | 
     
 | 
    /** 
 | 
     * 加入新的IoSession 
 | 
     * @param rtuAddr 
 | 
     * @param protocolName 
 | 
     * @param ioSession 
 | 
     */ 
 | 
    public static void putNewTcpSession(String rtuAddr, String protocolName, IoSession ioSession){ 
 | 
        synchronized (sessionTable){ 
 | 
            TcpSession tcpSe = sessionTable.get(rtuAddr) ; 
 | 
            if(tcpSe == null){ 
 | 
                tcpSe = new TcpSession() ; 
 | 
                tcpSe.protocolName = protocolName ; 
 | 
                tcpSe.ioSession = ioSession ; 
 | 
                sessionTable.put(rtuAddr, tcpSe) ; 
 | 
            }else{ 
 | 
                tcpSe.ioSession = ioSession ; 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
     
 | 
    /** 
 | 
     * 更新IoSession对应的rtuAddr 
 | 
     * @param oldRtuAddr 
 | 
     * @param newRtuAddr 
 | 
     * @param protocolName 
 | 
     * @param ioSession 
 | 
     */ 
 | 
    public static void changeRtuAddr(String oldRtuAddr, String newRtuAddr, String protocolName, IoSession ioSession){ 
 | 
        if(oldRtuAddr != null && newRtuAddr != null && !oldRtuAddr.equals(newRtuAddr)){ 
 | 
            synchronized (sessionTable){ 
 | 
                TcpSession tcpSe = sessionTable.get(oldRtuAddr) ; 
 | 
                if(tcpSe == null){ 
 | 
                    putNewTcpSession(newRtuAddr, protocolName, ioSession) ; 
 | 
                }else{ 
 | 
                    sessionTable.remove(oldRtuAddr) ; 
 | 
                    sessionTable.put(newRtuAddr, tcpSe) ; 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
     
 | 
    /** 
 | 
     * 得到TcpSession 
 | 
     * @param rtuAddr 
 | 
     * @return 
 | 
     */ 
 | 
    public static TcpSession getTcpSession(String rtuAddr){ 
 | 
        return sessionTable.get(rtuAddr) ; 
 | 
    } 
 | 
     
 | 
    /** 
 | 
     * 得到Tcp通信协议名称 
 | 
     * @param rtuAddr 
 | 
     * @return 
 | 
     */ 
 | 
    public static String getTcpProtocolName(String rtuAddr){ 
 | 
        TcpSession tcpSe = sessionTable.get(rtuAddr) ; 
 | 
        if(tcpSe != null){ 
 | 
            return tcpSe.protocolName ; 
 | 
        }else{ 
 | 
            return null ; 
 | 
        } 
 | 
    } 
 | 
     
 | 
    /** 
 | 
     * 得到所有在线情况 
 | 
     * @return 
 | 
     */ 
 | 
    public static HashMap<String, Boolean> allOnLine(){ 
 | 
        synchronized (sessionTable){ 
 | 
            HashMap<String, Boolean> map = new HashMap<String, Boolean>(); 
 | 
            Iterator<Entry<String, TcpSession>> it = sessionTable.entrySet().iterator() ; 
 | 
            Entry<String, TcpSession> entry = null ; 
 | 
            while(it.hasNext()){ 
 | 
                entry = it.next() ; 
 | 
                map.put(entry.getKey(), entry.getValue().ioSession.isConnected()) ; 
 | 
            } 
 | 
            return map ; 
 | 
        } 
 | 
    } 
 | 
    /** 
 | 
     * 得到所有RTU连接状态情况 
 | 
     * @return 
 | 
     */ 
 | 
    public static List<RtuSessionStatus> allConnectStatus(){ 
 | 
        synchronized (sessionTable){ 
 | 
            List<RtuSessionStatus> list = new ArrayList<RtuSessionStatus>(); 
 | 
            Iterator<Entry<String, TcpSession>> it = sessionTable.entrySet().iterator() ; 
 | 
            Entry<String, TcpSession> entry = null ; 
 | 
            while(it.hasNext()){ 
 | 
                entry = it.next() ; 
 | 
                RtuSessionStatus vo = new RtuSessionStatus() ; 
 | 
                vo.rtuAddr = entry.getKey() ; 
 | 
                IoSession se = entry.getValue().ioSession ; 
 | 
                vo.onTrueOffLine = se.isConnected() ; 
 | 
                InetSocketAddress sa = (InetSocketAddress)se.getRemoteAddress() ; 
 | 
                if(sa != null){ 
 | 
                    InetAddress inetAddr = sa.getAddress() ; 
 | 
                    if(inetAddr != null){ 
 | 
                        vo.ip = inetAddr.getHostAddress() ; 
 | 
                        vo.port = sa.getPort() ; 
 | 
                    } 
 | 
                } 
 | 
                list.add(vo) ; 
 | 
            } 
 | 
            return list ; 
 | 
        } 
 | 
    } 
 | 
     
 | 
     
 | 
    /** 
 | 
     * 得到IoSession 
 | 
     * @param rtuAddr 
 | 
     * @return 
 | 
     */ 
 | 
//    public IoSession getIoSession(String rtuAddr){ 
 | 
//        TcpSession tcpSe = sessionMap.get(rtuAddr) ; 
 | 
//        if(tcpSe != null){ 
 | 
//            return tcpSe.ioSession ; 
 | 
//        } 
 | 
//        return null ; 
 | 
//    } 
 | 
     
 | 
    /** 
 | 
     * 网络是否连接 
 | 
     * @param rtuAddr 
 | 
     * @return 
 | 
     */ 
 | 
    public static Boolean isConnect(String rtuAddr){ 
 | 
        TcpSession tcpSe = sessionTable.get(rtuAddr) ; 
 | 
        if(tcpSe != null){ 
 | 
            return tcpSe.ioSession.isConnected() ; 
 | 
        } 
 | 
        return null ; 
 | 
    } 
 | 
     
 | 
    /** 
 | 
     * 通过IoSession输出数据 
 | 
     * @param rtuAddr 
 | 
     * @param data 
 | 
     * @throws Exception 
 | 
     */ 
 | 
    public static void write(String rtuAddr, byte[] data) throws Exception{ 
 | 
        TcpSession tcpSe = sessionTable.get(rtuAddr) ; 
 | 
        if(tcpSe != null){ 
 | 
            if(tcpSe.ioSession.isConnected()){ 
 | 
                tcpSe.ioSession.write(data) ; 
 | 
            }else{ 
 | 
                throw new Exception("Rtu连接已经关闭!") ; 
 | 
            } 
 | 
        }else{ 
 | 
            throw new Exception("Rtu未曾上线!") ; 
 | 
        } 
 | 
    } 
 | 
     
 | 
    /** 
 | 
     * 设置上行数据时刻 
 | 
     * @param rtuAddr 
 | 
     */ 
 | 
    public static void cacheUpDataTime(String rtuAddr){ 
 | 
        TcpSession tcpSe = sessionTable.get(rtuAddr) ; 
 | 
        if(tcpSe != null){ 
 | 
            tcpSe.lastUpDataTime = System.currentTimeMillis() ; 
 | 
        } 
 | 
    } 
 | 
     
 | 
    /** 
 | 
     * 更新上行数据时刻 
 | 
     * 当上行数据时刻已经过去一定时长,上行数据时刻清空 
 | 
     */ 
 | 
    public static void updateUpDataTime(Long now){ 
 | 
        synchronized (sessionTable){ 
 | 
            Iterator<TcpSession> it = sessionTable.values().iterator() ; 
 | 
            TcpSession tcpSe ; 
 | 
            while(it.hasNext()){ 
 | 
                tcpSe = it.next() ; 
 | 
                if(tcpSe.lastUpDataTime != null){ 
 | 
                    if(now - tcpSe.lastUpDataTime > ServerProperties.lastUpDataTimeLive){ 
 | 
                        tcpSe.lastUpDataTime = null ; 
 | 
                    } 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
  
 | 
  
 | 
} 
 |