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 sessionTable = new HashMap() ; /** * 加入新的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 allOnLine(){ synchronized (sessionTable){ HashMap map = new HashMap(); Iterator> it = sessionTable.entrySet().iterator() ; Entry entry = null ; while(it.hasNext()){ entry = it.next() ; map.put(entry.getKey(), entry.getValue().ioSession.isConnected()) ; } return map ; } } /** * 得到所有RTU连接状态情况 * @return */ public static List allConnectStatus(){ synchronized (sessionTable){ List list = new ArrayList(); Iterator> it = sessionTable.entrySet().iterator() ; Entry 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 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 ; } } } } } }