|  | @@ -3,6 +3,7 @@ package com.ruoyi.sim.service.impl;
 | 
	
		
			
				|  |  |  import com.ruoyi.common.core.domain.AjaxResult;
 | 
	
		
			
				|  |  |  import com.ruoyi.sim.config.SimConfig;
 | 
	
		
			
				|  |  |  import com.ruoyi.sim.constant.CommConst;
 | 
	
		
			
				|  |  | +import com.ruoyi.sim.domain.Seat;
 | 
	
		
			
				|  |  |  import com.ruoyi.sim.domain.vo.SimSocketVo;
 | 
	
		
			
				|  |  |  import com.ruoyi.sim.domain.vo.SocketWrapValue;
 | 
	
		
			
				|  |  |  import org.apache.commons.lang3.StringUtils;
 | 
	
	
		
			
				|  | @@ -14,6 +15,7 @@ import org.springframework.stereotype.Service;
 | 
	
		
			
				|  |  |  import java.io.IOException;
 | 
	
		
			
				|  |  |  import java.net.Socket;
 | 
	
		
			
				|  |  |  import java.util.HashMap;
 | 
	
		
			
				|  |  | +import java.util.List;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import static com.ruoyi.sim.constant.CommConst.SOCKET_TIME_OUT;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -26,11 +28,13 @@ public class SocketService {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      private static final Logger l = LoggerFactory.getLogger(SocketService.class);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    private static final int INIT_SIZE = 16;
 | 
	
		
			
				|  |  | +    private static final int INIT_SIZE = 32;
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  |       * 6 hours
 | 
	
		
			
				|  |  | +     * 1000L * 60 * 60 * 6
 | 
	
		
			
				|  |  | +     * 1000L * 60 * 5
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  | -    private static final long LIMIT = 1000L * 60 * 60 * 6;
 | 
	
		
			
				|  |  | +    private static final long TIMEOUT_LIMIT = 1000L * 60 * 60 * 6;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  |       * key: ip:port
 | 
	
	
		
			
				|  | @@ -42,6 +46,8 @@ public class SocketService {
 | 
	
		
			
				|  |  |      private SimConfig config;
 | 
	
		
			
				|  |  |      @Autowired
 | 
	
		
			
				|  |  |      private FailedCountService failedCountService;
 | 
	
		
			
				|  |  | +    @Autowired
 | 
	
		
			
				|  |  | +    private SeatService seatService;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  |       * @param ip   ip v4.
 | 
	
	
		
			
				|  | @@ -49,15 +55,34 @@ public class SocketService {
 | 
	
		
			
				|  |  |       * @return true:socket ok!
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  |      public boolean isOk(final String ip, final Integer port) {
 | 
	
		
			
				|  |  | -        if (cachedMap.containsKey(ip)) {
 | 
	
		
			
				|  |  | -            Socket s = cachedMap.get(buildKey(ip, port)).getSocket();
 | 
	
		
			
				|  |  | +        final String key = buildKey(ip, port);
 | 
	
		
			
				|  |  | +        if (cachedMap.containsKey(key)) {
 | 
	
		
			
				|  |  | +            Socket s = cachedMap.get(key).getSocket();
 | 
	
		
			
				|  |  |              if (s != null) {
 | 
	
		
			
				|  |  | -                return (s.isConnected() && s.isBound() && !s.isClosed());
 | 
	
		
			
				|  |  | +                return (s.isConnected() && s.isBound() && !s.isClosed() && !isTimeout(ip, port));
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          return false;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    public boolean isNotOk(final String ip, final Integer port) {
 | 
	
		
			
				|  |  | +        return !isOk(ip, port);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    public boolean isTimeout(final String ip, final Integer port) {
 | 
	
		
			
				|  |  | +        final String key = buildKey(ip, port);
 | 
	
		
			
				|  |  | +        if (cachedMap.containsKey(key)) {
 | 
	
		
			
				|  |  | +            Long cached = cachedMap.get(key).getOkTimeMillis();
 | 
	
		
			
				|  |  | +            if (cached == null || cached == 0L) {
 | 
	
		
			
				|  |  | +                return true;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            if (System.currentTimeMillis() - cached > TIMEOUT_LIMIT) {
 | 
	
		
			
				|  |  | +                return false;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return true;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  |       * @param ip   ip v4.
 | 
	
		
			
				|  |  |       * @param port
 | 
	
	
		
			
				|  | @@ -88,8 +113,8 @@ public class SocketService {
 | 
	
		
			
				|  |  |              final String ip = ssv.getIp();
 | 
	
		
			
				|  |  |              final Integer port = ssv.getPort();
 | 
	
		
			
				|  |  |              final String key = buildKey(ip, port);
 | 
	
		
			
				|  |  | -            if (!isOk(ip, port)) {
 | 
	
		
			
				|  |  | -                l.info("openSocket cachedSocket is not ok!new socket ip = {}!", ip);
 | 
	
		
			
				|  |  | +            if (isNotOk(ip, port)) {
 | 
	
		
			
				|  |  | +                l.info("openSocket cachedSocket is not ok!new socket ip = {}:{}!", ip, port);
 | 
	
		
			
				|  |  |                  closeOne(ssv);
 | 
	
		
			
				|  |  |                  Socket s = new Socket(ip, port);
 | 
	
		
			
				|  |  |                  s.setSoTimeout(SOCKET_TIME_OUT);
 | 
	
	
		
			
				|  | @@ -97,8 +122,11 @@ public class SocketService {
 | 
	
		
			
				|  |  |                  cachedMap.put(key, value);
 | 
	
		
			
				|  |  |                  // failed count reset.
 | 
	
		
			
				|  |  |                  failedCountService.reset0(key);
 | 
	
		
			
				|  |  | +            } else {
 | 
	
		
			
				|  |  | +                l.info("openSocket cachedSocket cache ok!cached socket ip = {}:{}!", ip, port);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          } catch (IOException e) {
 | 
	
		
			
				|  |  | +            l.error(ssv.toString());
 | 
	
		
			
				|  |  |              throw new RuntimeException(e);
 | 
	
		
			
				|  |  |          } finally {
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -106,64 +134,74 @@ public class SocketService {
 | 
	
		
			
				|  |  |          return AjaxResult.success("openOneSocket Success!");
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  |       * todo:部分返回Aj结果。
 | 
	
		
			
				|  |  |       *
 | 
	
		
			
				|  |  | -     * @param ssvs
 | 
	
		
			
				|  |  |       * @return
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  | -    public AjaxResult openAll(final SimSocketVo[] ssvs) {
 | 
	
		
			
				|  |  | +    public AjaxResult openAll() {
 | 
	
		
			
				|  |  |          if (!config.isCommGlobal()) {
 | 
	
		
			
				|  |  |              l.warn("isCommGlobal == {} [模拟器通信被禁用!]", config.isCommGlobal());
 | 
	
		
			
				|  |  |              return AjaxResult.error("模拟器通信被禁用!");
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        for (SimSocketVo ssv : ssvs) {
 | 
	
		
			
				|  |  | -            openOne(ssv);
 | 
	
		
			
				|  |  | +        List<Seat> allSeat = seatService.listAllEnable();
 | 
	
		
			
				|  |  | +        for (Seat s : allSeat) {
 | 
	
		
			
				|  |  | +            openOne(new SimSocketVo(s.getSeatRs485Ip(), s.getSeatRs485Port()));
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          return AjaxResult.success("openAllSocket Success!");
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      public AjaxResult closeOne(final SimSocketVo ssv) {
 | 
	
		
			
				|  |  | -        String msgOk = "关闭Socket成功!";
 | 
	
		
			
				|  |  |          if (!config.isCommGlobal()) {
 | 
	
		
			
				|  |  |              l.warn("isCommGlobal == {} [模拟器通信被禁用!]", config.isCommGlobal());
 | 
	
		
			
				|  |  |              return AjaxResult.error("模拟器通信被禁用!");
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | +        String msgOk = "关闭Socket成功!";
 | 
	
		
			
				|  |  |          final String key = buildKey(ssv.getIp(), ssv.getPort());
 | 
	
		
			
				|  |  | -        if (!cachedMap.containsKey(key)) {
 | 
	
		
			
				|  |  | -            cachedMap.remove(key);
 | 
	
		
			
				|  |  | -            return AjaxResult.success(msgOk);
 | 
	
		
			
				|  |  | -        } else {
 | 
	
		
			
				|  |  | -            try {
 | 
	
		
			
				|  |  | +        try {
 | 
	
		
			
				|  |  | +            if (cachedMap.containsKey(key)) {
 | 
	
		
			
				|  |  |                  Socket s = cachedMap.get(key).getSocket();
 | 
	
		
			
				|  |  |                  s.getInputStream().close();
 | 
	
		
			
				|  |  |                  s.getOutputStream().close();
 | 
	
		
			
				|  |  |                  s.close();
 | 
	
		
			
				|  |  | -            } catch (IOException e) {
 | 
	
		
			
				|  |  | -                e.printStackTrace();
 | 
	
		
			
				|  |  | -            } finally {
 | 
	
		
			
				|  |  | -                cachedMap.remove(key);
 | 
	
		
			
				|  |  | -                // failed count reset.
 | 
	
		
			
				|  |  | -                failedCountService.reset0(key);
 | 
	
		
			
				|  |  | -                return AjaxResult.success(msgOk);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | +        } catch (IOException e) {
 | 
	
		
			
				|  |  | +            e.printStackTrace();
 | 
	
		
			
				|  |  | +        } finally {
 | 
	
		
			
				|  |  | +            cachedMap.remove(key);
 | 
	
		
			
				|  |  | +            // failed count reset.
 | 
	
		
			
				|  |  | +            failedCountService.reset0(key);
 | 
	
		
			
				|  |  | +            return AjaxResult.success(msgOk);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    public AjaxResult closeAll(final SimSocketVo[] ssvs) {
 | 
	
		
			
				|  |  | -        String msgOk = "关闭所有Socket成功!";
 | 
	
		
			
				|  |  | -        for (SimSocketVo ssv : ssvs) {
 | 
	
		
			
				|  |  | -            AjaxResult ar = closeOne(ssv);
 | 
	
		
			
				|  |  | -            if (ar != null && !ar.isSuccess()) {
 | 
	
		
			
				|  |  | -                return ar;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | +    public AjaxResult closeAll() {
 | 
	
		
			
				|  |  | +        if (!config.isCommGlobal()) {
 | 
	
		
			
				|  |  | +            l.warn("isCommGlobal == {} [模拟器通信被禁用!]", config.isCommGlobal());
 | 
	
		
			
				|  |  | +            return AjaxResult.error("模拟器通信被禁用!");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        final String msgOk = "关闭所有Socket成功!";
 | 
	
		
			
				|  |  | +        List<Seat> allSeat = seatService.listAllEnable();
 | 
	
		
			
				|  |  | +        for (Seat s : allSeat) {
 | 
	
		
			
				|  |  | +            closeOne(new SimSocketVo(s.getSeatRs485Ip(), s.getSeatRs485Port()));
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          return AjaxResult.success(msgOk);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  | +     * @param ip
 | 
	
		
			
				|  |  | +     * @param port
 | 
	
		
			
				|  |  | +     * @return
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    public Socket get(final String ip, final Integer port) {
 | 
	
		
			
				|  |  | +        final String key = buildKey(ip, port);
 | 
	
		
			
				|  |  | +        if (isNotOk(ip, port)) {
 | 
	
		
			
				|  |  | +            openOne(new SimSocketVo(ip, port));
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return cachedMap.get(key).getSocket();
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  |       * 初始化。
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  |      public void resetAll() {
 |