| 
					
				 | 
			
			
				@@ -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() { 
			 |