Jelajahi Sumber

新Socket改版后的问题解决。

tom 2 bulan lalu
induk
melakukan
b3151b2277
22 mengubah file dengan 527 tambahan dan 309 penghapusan
  1. 34 17
      pla-sim/01_SQL/02_table/mx_debug_fault.sql
  2. 0 16
      ruoyi-sim/src/main/java/com/ruoyi/sim/constant/CommConst.java
  3. 17 10
      ruoyi-sim/src/main/java/com/ruoyi/sim/controller/HardwareCommDebugController.java
  4. 11 3
      ruoyi-sim/src/main/java/com/ruoyi/sim/controller/RealExamController.java
  5. 10 4
      ruoyi-sim/src/main/java/com/ruoyi/sim/controller/TestIotController.java
  6. 9 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/domain/RealExamCollection.java
  7. 3 3
      ruoyi-sim/src/main/java/com/ruoyi/sim/domain/Seat.java
  8. 3 2
      ruoyi-sim/src/main/java/com/ruoyi/sim/domain/SimMsg.java
  9. 10 4
      ruoyi-sim/src/main/java/com/ruoyi/sim/domain/vo/SimSocketParamVo.java
  10. 108 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/domain/vo/SocketWrapCacheVo.java
  11. 0 62
      ruoyi-sim/src/main/java/com/ruoyi/sim/domain/vo/SocketWrapValue.java
  12. 7 10
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommCheckService.java
  13. 50 41
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommSendService.java
  14. 48 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommStrategy.java
  15. 0 62
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/FailedCountService.java
  16. 56 14
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/RealExamCollectionService.java
  17. 26 14
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/RealExamService.java
  18. 9 2
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/SeatService.java
  19. 3 1
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/SimService.java
  20. 2 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/SocketOldService.java
  21. 119 43
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/SocketService.java
  22. 2 1
      ruoyi-ui/vue.config.js

+ 34 - 17
pla-sim/01_SQL/02_table/mx_debug_fault.sql

@@ -11,7 +11,7 @@
  Target Server Version : 80032 (8.0.32-X-Cluster-8.4.19-20241112)
  File Encoding         : 65001
 
- Date: 14/02/2025 16:27:41
+ Date: 16/02/2025 21:01:28
 */
 
 SET NAMES utf8mb4;
@@ -35,25 +35,42 @@ CREATE TABLE `mx_debug_fault`  (
   `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '更新者',
   `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
   PRIMARY KEY (`ref_id`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 342 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'sim-调试故障表' ROW_FORMAT = DYNAMIC;
+) ENGINE = InnoDB AUTO_INCREMENT = 433 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'sim-调试故障表' ROW_FORMAT = DYNAMIC;
 
 -- ----------------------------
 -- Records of mx_debug_fault
 -- ----------------------------
-INSERT INTO `mx_debug_fault` VALUES (327, 169, '0003GZBW0001', '1', '', '1', '00000002', '0000000C', NULL, '2025-02-14 16:25:49', NULL, '2025-02-14 16:26:07');
-INSERT INTO `mx_debug_fault` VALUES (328, 169, '0003GZBW0002', '1', '', '2', '00000002', '00000002', NULL, '2025-02-14 16:25:50', NULL, '2025-02-14 16:26:07');
-INSERT INTO `mx_debug_fault` VALUES (329, 169, '0003GZBW0003', '1', '', '2', '0000000C', '0000000C', NULL, '2025-02-14 16:25:50', NULL, '2025-02-14 16:26:07');
-INSERT INTO `mx_debug_fault` VALUES (330, 169, '0003GZBW0004', '0', '', '0', '00000002', '00000002', NULL, '2025-02-14 16:25:50', NULL, '2025-02-14 16:26:07');
-INSERT INTO `mx_debug_fault` VALUES (331, 169, '0003GZBW0005', '0', '', '0', '00000000', '00000000', NULL, '2025-02-14 16:25:50', NULL, '2025-02-14 16:26:07');
-INSERT INTO `mx_debug_fault` VALUES (332, 169, '0003GZBW0006', '0', '', '0', '00000009', '00000009', NULL, '2025-02-14 16:25:50', NULL, '2025-02-14 16:26:07');
-INSERT INTO `mx_debug_fault` VALUES (333, 169, '0003GZBW0007', '0', '', '0', '00000000', '00000000', NULL, '2025-02-14 16:25:51', NULL, '2025-02-14 16:26:07');
-INSERT INTO `mx_debug_fault` VALUES (334, 169, '0003GZBW0008', '0', '', '0', '00000000', '00000000', NULL, '2025-02-14 16:25:51', NULL, '2025-02-14 16:26:07');
-INSERT INTO `mx_debug_fault` VALUES (335, 169, '0003GZBW0009', '0', '', '0', '00000000', '00000000', NULL, '2025-02-14 16:25:51', NULL, '2025-02-14 16:26:08');
-INSERT INTO `mx_debug_fault` VALUES (336, 169, '0003GZBW0010', '0', '', '0', '00000001', '00000001', NULL, '2025-02-14 16:25:51', NULL, '2025-02-14 16:26:08');
-INSERT INTO `mx_debug_fault` VALUES (337, 169, '0003GZBW0011', '0', '', '0', '0000000F', '0000000F', NULL, '2025-02-14 16:25:52', NULL, '2025-02-14 16:26:08');
-INSERT INTO `mx_debug_fault` VALUES (338, 169, '0003GZBW0012', '0', '', '0', '00000000', '00000000', NULL, '2025-02-14 16:25:52', NULL, '2025-02-14 16:26:08');
-INSERT INTO `mx_debug_fault` VALUES (339, 169, '0003GZBW0013', '0', '', '0', '00000001', '00000001', NULL, '2025-02-14 16:25:52', NULL, '2025-02-14 16:26:08');
-INSERT INTO `mx_debug_fault` VALUES (340, 169, '0003GZBW0014', '0', '', '0', '00000001', '00000001', NULL, '2025-02-14 16:25:52', NULL, '2025-02-14 16:26:08');
-INSERT INTO `mx_debug_fault` VALUES (341, 169, '0003GZBW0015', '0', '', '0', '00000000', '00000000', NULL, '2025-02-14 16:25:52', NULL, '2025-02-14 16:26:08');
+INSERT INTO `mx_debug_fault` VALUES (401, 8, '0001GZBW0001', '1', '', '2', '0000000E', '0000000E', NULL, '2025-02-16 20:15:05', NULL, '2025-02-16 20:30:11');
+INSERT INTO `mx_debug_fault` VALUES (402, 8, '0001GZBW0002', '0', '', '0', '00000013', '00000013', NULL, '2025-02-16 20:15:05', NULL, '2025-02-16 20:30:12');
+INSERT INTO `mx_debug_fault` VALUES (403, 8, '0001GZBW0003', '1', '', '2', '01000000', '01000000', NULL, '2025-02-16 20:15:06', NULL, '2025-02-16 20:30:12');
+INSERT INTO `mx_debug_fault` VALUES (404, 8, '0001GZBW0004', '0', '', '0', '0000000F', '0000000F', NULL, '2025-02-16 20:15:06', NULL, '2025-02-16 20:30:12');
+INSERT INTO `mx_debug_fault` VALUES (405, 8, '0001GZBW0005', '1', '', '2', '00000000', '00000000', NULL, '2025-02-16 20:15:06', NULL, '2025-02-16 20:30:12');
+INSERT INTO `mx_debug_fault` VALUES (406, 8, '0001GZBW0006', '0', '', '0', '00000006', '00000006', NULL, '2025-02-16 20:15:06', NULL, '2025-02-16 20:30:12');
+INSERT INTO `mx_debug_fault` VALUES (407, 8, '0001GZBW0007', '0', '', '0', '00000001', '00000001', NULL, '2025-02-16 20:15:07', NULL, '2025-02-16 20:30:12');
+INSERT INTO `mx_debug_fault` VALUES (408, 8, '0001GZBW0008', '0', '', '0', '00000002', '00000002', NULL, '2025-02-16 20:15:07', NULL, '2025-02-16 20:30:12');
+INSERT INTO `mx_debug_fault` VALUES (409, 8, '0001GZBW0009', '0', '', '0', '00000002', '00000002', NULL, '2025-02-16 20:15:07', NULL, '2025-02-16 20:30:12');
+INSERT INTO `mx_debug_fault` VALUES (410, 8, '0001GZBW0010', '0', '', '0', '00000004', '00000004', NULL, '2025-02-16 20:15:07', NULL, '2025-02-16 20:30:13');
+INSERT INTO `mx_debug_fault` VALUES (411, 9, '0001GZBW0001', '1', '', '2', '0000000E', '0000000E', NULL, '2025-02-16 20:41:24', NULL, '2025-02-16 20:41:29');
+INSERT INTO `mx_debug_fault` VALUES (412, 9, '0001GZBW0002', '1', '', '2', '00000016', '00000016', NULL, '2025-02-16 20:41:25', NULL, '2025-02-16 20:41:29');
+INSERT INTO `mx_debug_fault` VALUES (413, 9, '0001GZBW0003', '1', '', '2', '01000008', '01000008', NULL, '2025-02-16 20:41:25', NULL, '2025-02-16 20:41:29');
+INSERT INTO `mx_debug_fault` VALUES (414, 9, '0001GZBW0004', '0', '', '0', '00000019', '00000019', NULL, '2025-02-16 20:41:25', NULL, '2025-02-16 20:41:29');
+INSERT INTO `mx_debug_fault` VALUES (415, 9, '0001GZBW0005', '1', '', '2', '00000002', '00000002', NULL, '2025-02-16 20:41:25', NULL, '2025-02-16 20:41:29');
+INSERT INTO `mx_debug_fault` VALUES (416, 9, '0001GZBW0006', '0', '', '0', '00000009', '00000009', NULL, '2025-02-16 20:41:26', NULL, '2025-02-16 20:41:30');
+INSERT INTO `mx_debug_fault` VALUES (417, 9, '0001GZBW0007', '0', '', '0', '00000001', '00000001', NULL, '2025-02-16 20:41:26', NULL, '2025-02-16 20:41:30');
+INSERT INTO `mx_debug_fault` VALUES (418, 9, '0001GZBW0008', '0', '', '0', '00000002', '00000002', NULL, '2025-02-16 20:41:26', NULL, '2025-02-16 20:41:30');
+INSERT INTO `mx_debug_fault` VALUES (419, 9, '0001GZBW0009', '0', '', '0', '00000002', '00000002', NULL, '2025-02-16 20:41:26', NULL, '2025-02-16 20:41:30');
+INSERT INTO `mx_debug_fault` VALUES (420, 9, '0001GZBW0010', '0', '', '0', '00000001', '00000001', NULL, '2025-02-16 20:41:27', NULL, '2025-02-16 20:41:30');
+INSERT INTO `mx_debug_fault` VALUES (421, 87, '0002GZBW0001', '1', '', '0', '00000001', '', NULL, '2025-02-16 20:52:52', NULL, NULL);
+INSERT INTO `mx_debug_fault` VALUES (422, 87, '0002GZBW0002', '1', '', '0', '00000014', '', NULL, '2025-02-16 20:52:52', NULL, NULL);
+INSERT INTO `mx_debug_fault` VALUES (423, 87, '0002GZBW0003', '1', '', '0', '00000000', '', NULL, '2025-02-16 20:52:52', NULL, NULL);
+INSERT INTO `mx_debug_fault` VALUES (424, 87, '0002GZBW0004', '0', '', '0', '00000007', '', NULL, '2025-02-16 20:52:52', NULL, NULL);
+INSERT INTO `mx_debug_fault` VALUES (425, 87, '0002GZBW0005', '0', '', '0', '00000000', '', NULL, '2025-02-16 20:52:53', NULL, NULL);
+INSERT INTO `mx_debug_fault` VALUES (426, 87, '0002GZBW0006', '0', '', '0', '00000013', '', NULL, '2025-02-16 20:52:53', NULL, NULL);
+INSERT INTO `mx_debug_fault` VALUES (427, 87, '0002GZBW0007', '0', '', '0', '00000004', '', NULL, '2025-02-16 20:52:53', NULL, NULL);
+INSERT INTO `mx_debug_fault` VALUES (428, 87, '0002GZBW0008', '0', '', '0', '00000013', '', NULL, '2025-02-16 20:52:53', NULL, NULL);
+INSERT INTO `mx_debug_fault` VALUES (429, 87, '0002GZBW0009', '0', '', '0', '00000001', '', NULL, '2025-02-16 20:52:54', NULL, NULL);
+INSERT INTO `mx_debug_fault` VALUES (430, 87, '0002GZBW0010', '0', '', '0', '00000000', '', NULL, '2025-02-16 20:52:54', NULL, NULL);
+INSERT INTO `mx_debug_fault` VALUES (431, 87, '0002GZBW0011', '0', '', '0', '00000013', '', NULL, '2025-02-16 20:52:54', NULL, NULL);
+INSERT INTO `mx_debug_fault` VALUES (432, 87, '0002GZBW0012', '0', '', '0', '0000000E', '', NULL, '2025-02-16 20:52:54', NULL, NULL);
 
 SET FOREIGN_KEY_CHECKS = 1;

+ 0 - 16
ruoyi-sim/src/main/java/com/ruoyi/sim/constant/CommConst.java

@@ -72,22 +72,6 @@ public interface CommConst {
      */
     int LENGTH_24 = 24;
 
-    /**
-     * 请求间隔睡眠时间-long
-     * default:200L
-     */
-    Long SLEEP_LONG = 300L;
-    /**
-     * 请求间隔睡眠时间-mid
-     * default:100L
-     */
-    Long SLEEP_MID = 1000L;
-    /**
-     * 请求间隔睡眠时间-short
-     * default:64L
-     */
-    Long SLEEP_SHORT = 200L;
-
     int SOCKET_TIME_OUT = 50;
 
     int PING_TIME_OUT = 500;

+ 17 - 10
ruoyi-sim/src/main/java/com/ruoyi/sim/controller/HardwareCommDebugController.java

@@ -72,12 +72,12 @@ public class HardwareCommDebugController extends BaseController {
     }
 
     @GetMapping(value = "/debugClearAllOnlineSimAllFault/")
-    @ApiOperation("debug清除所有在线模拟器所有故障")
+    @ApiOperation("debug清除所有在线模拟器所有故障")
     public AjaxResult debugClearAllOnlineSimAllFault() {
         return commSendService.debugClearAllOnlineSimAllFault();
     }
 
-    @GetMapping(value = "/debugWriteOneFault/{simNum}/{bindHardwareMsg}")
+    @GetMapping(value = "/debugWriteOneFault/{seatId}/{bindHardwareMsg}")
     @ApiOperation("debug下发一个故障")
     public AjaxResult debugWriteOneFault(@PathVariable("seatId") final Long seatId,
                                          @PathVariable("bindHardwareMsg") final String bindHardwareMsg) {
@@ -90,16 +90,22 @@ public class HardwareCommDebugController extends BaseController {
         return success(commSendService.debugWriteAllFault(seatId));
     }
 
-    @GetMapping(value = "/debugWriteSelectedFaultBySimNum/{simNum}/{faultIds}")
+    @GetMapping(value = "/debugWriteSelectedFaultBySimNum/{seatId}/{faultIds}")
     @ApiOperation("debug下发所选故障,保存[debug_fault]表中,类似开始考试")
     public AjaxResult debugWriteSelectedFaultBySimNum(@PathVariable("seatId") final Long seatId,
                                                       @PathVariable("faultIds") final String[] faultIds,
                                                       @RequestParam final Boolean checkReplace) {
         return commSendService.debugWriteSelectedFaultBySimNum(seatId, faultIds, checkReplace);
     }
-    @GetMapping(value = "/buildMsg/")
 
-    @ApiOperation("buildMsg")
+    @GetMapping(value = "/debugRefreshAllSeat/")
+    @ApiOperation("debug模拟器扫描")
+    public AjaxResult debugRefreshAllSeat() {
+        return commSendService.debugRefreshAllSeat();
+    }
+
+    @GetMapping(value = "/buildMsg/")
+    @ApiOperation("拼写带CRC16校验的命令")
     public AjaxResult buildSendMsg(@RequestParam final String simNum,
                                    @RequestParam final String orn,
                                    @RequestParam final String cmd,
@@ -108,12 +114,13 @@ public class HardwareCommDebugController extends BaseController {
         return commBuildService.buildSendMsgAR(simNum, orn, cmd, cmdId, data);
     }
 
-    @ApiOperation("buildMsgAndSend")
+    @GetMapping(value = "/buildMsgAndSend/")
+    @ApiOperation("拼写带CRC16校验的命令并发送")
     public AjaxResult buildMsgAndSend(@RequestParam final String simNum,
-                                   @RequestParam final String orn,
-                                   @RequestParam final String cmd,
-                                   @RequestParam final String cmdId,
-                                   @RequestParam final String data) {
+                                      @RequestParam final String orn,
+                                      @RequestParam final String cmd,
+                                      @RequestParam final String cmdId,
+                                      @RequestParam final String data) {
         // todo:
         return commBuildService.buildSendMsgAR(simNum, orn, cmd, cmdId, data);
     }

+ 11 - 3
ruoyi-sim/src/main/java/com/ruoyi/sim/controller/RealExamController.java

@@ -103,25 +103,33 @@ public class RealExamController extends BaseController {
         return realExamService.studentLoopAnsweringRealExam(examId);
     }
 
+    // todo:交卷验证交卷ip
+//    @GetMapping("/student/exam/submit/{examId}")
+//    @ApiOperation("[学生][正式使用]交卷考试")
+//    public AjaxResult studentSubmitRealExam(@PathVariable("examId") Long examId, @RequestParam final String ip) {
+//        l.info("[学生][正式使用]交卷考试");
+//        return realExamService.studentSubmitRealExam(examId, ip, RealExamCollection.Type.EXAM);
+//    }
+
     @GetMapping("/student/exam/submit/{examId}")
     @ApiOperation("[学生][正式使用]交卷考试")
     public AjaxResult studentSubmitRealExam(@PathVariable("examId") Long examId) {
         l.info("[学生][正式使用]交卷考试");
-        return realExamService.studentSubmitRealExam(examId);
+        return realExamService.studentSubmitRealExam(examId, null, RealExamCollection.Type.EXAM);
     }
 
     @GetMapping("/student/exercise/submit/{examId}")
     @ApiOperation("[学生][正式使用]交卷练习")
     public AjaxResult studentSubmitRealExercise(@PathVariable("examId") Long examId) {
         l.info("[学生][正式使用]交卷练习");
-        return realExamService.studentSubmitRealExam(examId);
+        return realExamService.studentSubmitRealExam(examId, null, RealExamCollection.Type.EXERCISE);
     }
 
     @GetMapping("/student/self-exercise/submit/{examId}")
     @ApiOperation("[学生][正式使用]交卷自主练习")
     public AjaxResult studentSubmitRealSelfExercise(@PathVariable("examId") Long examId) {
         l.info("[学生][正式使用]交卷自主练习");
-        return realExamService.studentSubmitRealExam(examId);
+        return realExamService.studentSubmitRealExam(examId, null, RealExamCollection.Type.SELF_EXERCISE);
     }
 
     @GetMapping("/student/exam/report/{examId}")

+ 10 - 4
ruoyi-sim/src/main/java/com/ruoyi/sim/controller/TestIotController.java

@@ -5,7 +5,7 @@ import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.sim.domain.Fault;
 import com.ruoyi.sim.domain.RealExam;
 import com.ruoyi.sim.domain.Seat;
-import com.ruoyi.sim.domain.vo.SimSocketVo;
+import com.ruoyi.sim.domain.vo.SimSocketParamVo;
 import com.ruoyi.sim.service.impl.*;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -89,7 +89,7 @@ public class TestIotController extends BaseController {
             }
             break;
             case 24: {
-                realExamService.studentSubmitRealExam(examId);
+                realExamService.studentSubmitRealExam(examId, null, null);
                 //
             }
             break;
@@ -102,8 +102,10 @@ public class TestIotController extends BaseController {
                 return aj;
             }
             case 27: {
-                socketService.closeOne(new SimSocketVo("192.168.1.202", 11001));
-                socketService.closeOne(new SimSocketVo("192.168.1.202", 11008));
+                // socketService.closeOne(new SimSocketVo("192.168.1.202", 33301));
+
+                socketService.openOne(new SimSocketParamVo(SocketService.IP_TEST, SocketService.PORT_TEST), true);
+                // socketService.closeOne(new SimSocketVo("192.168.1.202", 11008));
             }
             case 100: {
                 return socketService.tryOpenAll();
@@ -115,6 +117,10 @@ public class TestIotController extends BaseController {
             case 102: {
                 return commCheckService.checkAllSeatAndSimState();
             }
+            case 200: {
+                String ip = "192.168.1.201";
+                return commCheckService.checkPingRs485State(ip);
+            }
         }
         return AjaxResult.success("ZZZZZZZZZZZZZZZZZZZZ");
     }

+ 9 - 0
ruoyi-sim/src/main/java/com/ruoyi/sim/domain/RealExamCollection.java

@@ -203,8 +203,17 @@ public class RealExamCollection extends BaseEntity {
     }
 
     public interface Type {
+        /**
+         * 训练
+         */
         String EXERCISE = "1";
+        /**
+         * 练习
+         */
         String SELF_EXERCISE = "2";
+        /**
+         * 考试
+         */
         String EXAM = "3";
     }
 

+ 3 - 3
ruoyi-sim/src/main/java/com/ruoyi/sim/domain/Seat.java

@@ -1,6 +1,6 @@
 package com.ruoyi.sim.domain;
 
-import com.ruoyi.sim.domain.vo.SimSocketVo;
+import com.ruoyi.sim.domain.vo.SimSocketParamVo;
 import org.apache.commons.lang3.builder.ToStringBuilder;
 import org.apache.commons.lang3.builder.ToStringStyle;
 import com.ruoyi.common.annotation.Excel;
@@ -157,7 +157,7 @@ public class Seat extends BaseEntity {
         String DISABLE = "5";
     }
 
-    public SimSocketVo toSimSocketVo() {
-        return new SimSocketVo(this.getSeatRs485Ip(), this.getSeatRs485Port());
+    public SimSocketParamVo toSimSocketParamVo() {
+        return new SimSocketParamVo(this.getSeatRs485Ip(), this.getSeatRs485Port());
     }
 }

+ 3 - 2
ruoyi-sim/src/main/java/com/ruoyi/sim/domain/SimMsg.java

@@ -252,8 +252,9 @@ public class SimMsg extends BaseEntity {
     public interface Result {
         Integer DEFAULT_VALUE = 0;
         Integer SUCCESS = 200;
-        Integer RECEIVE_CHECK_FAIL = 500;
-        Integer SOCKET_EXCEPTION = 501;
+        Integer SOCKET_CONNECT_EXCEPTION = 501;
+        Integer SOCKET_TIMEOUT_EXCEPTION = 502;
+        Integer RECEIVE_CHECK_FAIL = 520;
     }
 
     public SimMsg() {

+ 10 - 4
ruoyi-sim/src/main/java/com/ruoyi/sim/domain/vo/SimSocketVo.java → ruoyi-sim/src/main/java/com/ruoyi/sim/domain/vo/SimSocketParamVo.java

@@ -5,8 +5,9 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.builder.EqualsBuilder;
 import org.apache.commons.lang3.builder.HashCodeBuilder;
 import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
 
-public class SimSocketVo {
+public class SimSocketParamVo {
 
     /**
      * ip v4.
@@ -17,7 +18,7 @@ public class SimSocketVo {
      */
     private Integer port;
 
-    public SimSocketVo(String ip, Integer port) {
+    public SimSocketParamVo(String ip, Integer port) {
         this.ip = ip;
         this.port = port;
     }
@@ -40,7 +41,7 @@ public class SimSocketVo {
 
     @Override
     public String toString() {
-        return new ToStringBuilder(this)
+        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
                 .append("ip", ip)
                 .append("port", port)
                 .toString();
@@ -52,7 +53,7 @@ public class SimSocketVo {
 
         if (o == null || getClass() != o.getClass()) return false;
 
-        SimSocketVo that = (SimSocketVo) o;
+        SimSocketParamVo that = (SimSocketParamVo) o;
 
         return new EqualsBuilder().append(ip, that.ip).append(port, that.port).isEquals();
     }
@@ -62,6 +63,11 @@ public class SimSocketVo {
         return new HashCodeBuilder(17, 37).append(ip).append(port).toHashCode();
     }
 
+    /**
+     * 拼装ip+port的key。
+     *
+     * @return
+     */
     public String toKey() {
         if (StringUtils.isBlank(ip)) {
             throw new IllegalArgumentException("ip error");

+ 108 - 0
ruoyi-sim/src/main/java/com/ruoyi/sim/domain/vo/SocketWrapCacheVo.java

@@ -0,0 +1,108 @@
+package com.ruoyi.sim.domain.vo;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.net.Socket;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class SocketWrapCacheVo {
+
+    /**
+     * ip v4.
+     */
+    private String ip;
+
+    /**
+     * port.
+     */
+    private Integer port;
+
+    private Socket socket;
+
+    /**
+     * 每个Socket都有。
+     */
+    private Long okTimeMillis;
+
+    /**
+     * 每个Socket都有。
+     */
+    private Long previousSendSleep = 0L;
+
+    /**
+     * 每个Socket都有。
+     * 重试次数。
+     * default 0.
+     */
+    private AtomicInteger failedCount = new AtomicInteger(0);
+
+    public SocketWrapCacheVo() {
+    }
+
+    public SocketWrapCacheVo(String ip, Integer port, Socket socket, Long okTimeMillis) {
+        this.ip = ip;
+        this.port = port;
+        this.socket = socket;
+        this.okTimeMillis = okTimeMillis;
+    }
+
+    public String getIp() {
+        return ip;
+    }
+
+    public void setIp(String ip) {
+        this.ip = ip;
+    }
+
+    public Integer getPort() {
+        return port;
+    }
+
+    public void setPort(Integer port) {
+        this.port = port;
+    }
+
+    public Socket getSocket() {
+        return socket;
+    }
+
+    public void setSocket(Socket socket) {
+        this.socket = socket;
+    }
+
+    public Long getOkTimeMillis() {
+        return okTimeMillis;
+    }
+
+    public void setOkTimeMillis(Long okTimeMillis) {
+        this.okTimeMillis = okTimeMillis;
+    }
+
+    public Long getPreviousSendSleep() {
+        return previousSendSleep;
+    }
+
+    public void setPreviousSendSleep(Long previousSendSleep) {
+        this.previousSendSleep = previousSendSleep;
+    }
+
+    public AtomicInteger getFailedCount() {
+        return failedCount;
+    }
+
+    public void setFailedCount(AtomicInteger failedCount) {
+        this.failedCount = failedCount;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
+                .append("ip", ip)
+                .append("port", port)
+                .append("socket", socket)
+                .append("okTimeMillis", okTimeMillis)
+                .append("failedCount", failedCount)
+                .toString();
+    }
+}

+ 0 - 62
ruoyi-sim/src/main/java/com/ruoyi/sim/domain/vo/SocketWrapValue.java

@@ -1,62 +0,0 @@
-package com.ruoyi.sim.domain.vo;
-
-import org.apache.commons.lang3.builder.ToStringBuilder;
-
-import java.net.Socket;
-
-public class SocketWrapValue {
-
-    /**
-     * ip v4.
-     */
-    private String ip;
-
-    /**
-     * port.
-     */
-    private Integer port;
-
-    private Socket socket;
-
-    private Long okTimeMillis;
-
-    public SocketWrapValue(String ip, Integer port, Socket socket, Long okTimeMillis) {
-        this.ip = ip;
-        this.port = port;
-        this.socket = socket;
-        this.okTimeMillis = okTimeMillis;
-    }
-
-    public String getIp() {
-        return ip;
-    }
-
-    public void setIp(String ip) {
-        this.ip = ip;
-    }
-
-    public Socket getSocket() {
-        return socket;
-    }
-
-    public void setSocket(Socket socket) {
-        this.socket = socket;
-    }
-
-    public Long getOkTimeMillis() {
-        return okTimeMillis;
-    }
-
-    public void setOkTimeMillis(Long okTimeMillis) {
-        this.okTimeMillis = okTimeMillis;
-    }
-
-    @Override
-    public String toString() {
-        return new ToStringBuilder(this)
-                .append("ip", ip)
-                .append("socket", socket)
-                .append("okTimeMillis", okTimeMillis)
-                .toString();
-    }
-}

+ 7 - 10
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommCheckService.java

@@ -36,9 +36,9 @@ public class CommCheckService {
     @Autowired
     private CommSendService commSendService;
     @Autowired
-    private FailedCountService failedCountService;
-    @Autowired
     private SocketService socketService;
+    @Autowired
+    private CommStrategy commStrategy;
 
     /**
      * 等同于ping命令。
@@ -120,7 +120,6 @@ public class CommCheckService {
      * @param important true:重要的场景 开始考试 重试次数不同,也会进行序列号检查。false:不重要场景 定时巡查。
      * @return
      */
-    @Transactional
     public AjaxResult checkOneSeatState(final Seat seat, final boolean important) {
         // check args.
         if (seat == null) {
@@ -135,7 +134,7 @@ public class CommCheckService {
             retryTotalCount = CommConst.RETRY_COUNT_0;
         }
         SimMsg smS01 = commBuildService.buildSendMsgWhichSim();
-        SimMsg smR01 = commSendService.send(smS01, seat, null, retryTotalCount, CommConst.SLEEP_SHORT);
+        SimMsg smR01 = commSendService.send(smS01, seat, null, retryTotalCount, commStrategy.getSleepShort());
         Integer result = smR01.getResult();
         if (Objects.equals(result, SimMsg.Result.SUCCESS)) {
             final String simNum = CommParseUtils.subSimNum(smR01);
@@ -155,7 +154,7 @@ public class CommCheckService {
             return AjaxResult.success(msg);
         } else if (Objects.equals(result, SimMsg.Result.RECEIVE_CHECK_FAIL)) {
             return AjaxResult.error("失败,报文回复异常。");
-        } else if (Objects.equals(result, SimMsg.Result.SOCKET_EXCEPTION)) {
+        } else if (Objects.equals(result, SimMsg.Result.SOCKET_CONNECT_EXCEPTION)) {
             // 更新SimId
             seatService.updateSimIdBySeatNum(seat.getSeatNum(), Sim.ID_0);
             String msgTemp = "座号[{0}]-没有连接任何接模拟器,检查线缆连接和线缆开关";
@@ -224,7 +223,7 @@ public class CommCheckService {
         }
         Sim sim = simService.selectSimBySimId(seat.getCurrentSimId());
         SimMsg smS = commBuildService.buildSendMsgReadSimType(sim.getSimNum());
-        SimMsg smR = commSendService.send(smS, seat, sim, retryTotalCount, CommConst.SLEEP_SHORT);
+        SimMsg smR = commSendService.send(smS, seat, sim, retryTotalCount, commStrategy.getSleepShort());
         if (StringUtils.isNotBlank(smR.getReceiveMsg())) {
             final String content = CommParseUtils.subContentData(smR);
             switch (targetSimType) {
@@ -283,13 +282,11 @@ public class CommCheckService {
         }
         Sim sim = simService.selectSimBySimId(seat.getCurrentSimId());
         SimMsg smS02 = commBuildService.buildSendMsgReadSimType(sim.getSimNum());
-        SimMsg smR02 = commSendService.send(smS02, seat, sim, retryTotalCount, CommConst.SLEEP_SHORT);
+        SimMsg smR02 = commSendService.send(smS02, seat, sim, retryTotalCount, commStrategy.getSleepShort());
         if (StringUtils.isNotBlank(smR02.getReceiveMsg())) {
             // 只要返回正确报文,即认为在线。
             simService.updateSimStateBySimId(sim.getSimId(), Sim.State.ONLINE);
-            // SocketOldService实现。
-            // socketOldService.commFailCountClearOne(sim.getSimId());
-            failedCountService.reset0(seat.toSimSocketVo());
+            socketService.failedReset0(seat.toSimSocketParamVo());
             return AjaxResult.success("成功,检查一个模拟器[" + sim.getSimNum() + "]OK!");
         }
         return AjaxResult.error("失败,检查一个模拟器[" + sim.getSimNum() + "]在线状态执行错误!");

+ 50 - 41
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommSendService.java

@@ -3,10 +3,9 @@ package com.ruoyi.sim.service.impl;
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.utils.DateUtils;
 import com.ruoyi.sim.config.SimConfig;
-import com.ruoyi.sim.config.SimDebugConfig;
 import com.ruoyi.sim.constant.CommConst;
 import com.ruoyi.sim.domain.*;
-import com.ruoyi.sim.domain.vo.SimSocketVo;
+import com.ruoyi.sim.domain.vo.SimSocketParamVo;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.LoggerFactory;
 import org.slf4j.Logger;
@@ -55,13 +54,13 @@ public class CommSendService {
     @Autowired
     private SocketService socketService;
     @Autowired
-    private FailedCountService failedCountService;
-    @Autowired
     private CommCheckService commCheckService;
     @Autowired
     CommReceiveService commReceiveService;
     @Autowired
     private SimConfig config;
+    @Autowired
+    private CommStrategy commStrategy;
 
     /**
      * 定时任务。
@@ -367,7 +366,7 @@ public class CommSendService {
         Seat seat = seatService.selectSeatBySeatId(seatId);
         Sim sim = gggSimBySeatId(seatId);
         SimMsg sm = commBuildService.buildSendMsgReadSimType(sim.getSimNum());
-        return send(sm, seat, sim, CommConst.RETRY_COUNT_0, CommConst.SLEEP_SHORT);
+        return send(sm, seat, sim, CommConst.RETRY_COUNT_0, commStrategy.getSleepShort());
     }
 
     /**
@@ -381,7 +380,7 @@ public class CommSendService {
         Seat seat = seatService.selectSeatBySeatId(seatId);
         Sim sim = gggSimBySeatId(seatId);
         SimMsg sm = commBuildService.buildSendMsgClearFault(sim.getSimNum(), bindHardwareMsg);
-        return send(sm, seat, sim, RETRY_COUNT_CLEAR_ONE_FAULT, SLEEP_LONG);
+        return send(sm, seat, sim, RETRY_COUNT_CLEAR_ONE_FAULT, commStrategy.getSleepLong());
     }
 
     public AjaxResult debugClearAllOnlineSimAllFault() {
@@ -440,7 +439,7 @@ public class CommSendService {
 
         // step1
         SimMsg smS = commBuildService.buildSendMsgClearFault(sim.getSimNum(), f.getBindHardwareMsg());
-        SimMsg smR = send(smS, seat, sim, RETRY_COUNT_CLEAR_ONE_FAULT, SLEEP_LONG);
+        SimMsg smR = send(smS, seat, sim, RETRY_COUNT_CLEAR_ONE_FAULT, commStrategy.getSleepLong());
         if (reF != null) {
             simReceiveService.clearOneFault(smR, sim, reF, f);
         } else {
@@ -474,7 +473,7 @@ public class CommSendService {
         Seat seat = seatService.selectSeatBySeatId(seatId);
         Sim sim = gggSimBySeatId(seatId);
         SimMsg sm = commBuildService.buildSendMsgWriteFault(sim.getSimNum(), bindHardwareMsg);
-        return send(sm, seat, sim, RETRY_COUNT_WRITE_ONE_FAULT, SLEEP_LONG);
+        return send(sm, seat, sim, RETRY_COUNT_WRITE_ONE_FAULT, commStrategy.getSleepLong());
     }
 
     /**
@@ -558,6 +557,12 @@ public class CommSendService {
         return AjaxResult.success("下发故障流程执行成功!");
     }
 
+    public AjaxResult debugRefreshAllSeat() {
+
+
+        return AjaxResult.success("执行成功!");
+    }
+
     private String[] getGZBWBySimType(String simType) {
         if (StringUtils.isBlank(simType)) {
             return new String[0];
@@ -607,7 +612,7 @@ public class CommSendService {
         // todo:ref is null.
         // 下发故障
         SimMsg smA1 = commBuildService.buildSendMsgWriteFault(sim.getSimNum(), f.getBindHardwareMsg());
-        SimMsg smA2 = send(smA1, seat, sim, RETRY_COUNT_WRITE_ONE_FAULT, SLEEP_LONG);
+        SimMsg smA2 = send(smA1, seat, sim, RETRY_COUNT_WRITE_ONE_FAULT, commStrategy.getSleepLong());
     }
 
     /**
@@ -653,7 +658,7 @@ public class CommSendService {
     public AjaxResult readOneSimOneFaultCheck(Seat seat, Sim sim, Fault f) {
         l.info("readOneSimOneFaultCheck sim = {},f = {}", sim, f);
         SimMsg sm1 = commBuildService.buildSendMsgReadFaultResistance(sim.getSimNum(), f.getBindHardwareMsg());
-        SimMsg sm2 = send(sm1, seat, sim, RETRY_COUNT_CHECK_ONE_FAULT, SLEEP_LONG);
+        SimMsg sm2 = send(sm1, seat, sim, RETRY_COUNT_CHECK_ONE_FAULT, commStrategy.getSleepLong());
         return simReceiveService.getOneFaultCheck(sm2, sim, f);
     }
 
@@ -699,7 +704,7 @@ public class CommSendService {
         l.info("readOneSimOneFaultFirstTime");
         // 读取一次当前电阻代表值作为出题值。
         SimMsg sm1 = commBuildService.buildSendMsgReadFaultResistance(sim.getSimNum(), f.getBindHardwareMsg());
-        SimMsg sm2 = send(sm1, seat, sim, RETRY_COUNT_WRITE_ONE_FAULT, SLEEP_LONG);
+        SimMsg sm2 = send(sm1, seat, sim, RETRY_COUNT_WRITE_ONE_FAULT, commStrategy.getSleepLong());
         simReceiveService.setFaultQuestionValue(sm2, sim, ref, f, faultIds);
     }
 
@@ -714,7 +719,7 @@ public class CommSendService {
         Seat seat = seatService.selectSeatBySeatId(seatId);
         Sim sim = gggSimBySeatId(seatId);
         SimMsg sm = commBuildService.buildSendMsgReadFaultResistance(sim.getSimNum(), bindHardwareMsg);
-        return send(sm, seat, null, RETRY_COUNT_0, SLEEP_SHORT);
+        return send(sm, seat, null, RETRY_COUNT_0, commStrategy.getSleepShort());
     }
 
     /**
@@ -745,20 +750,21 @@ public class CommSendService {
         SimMsg sm2 = null;
         if (reF != null && refState != null) {
             if (RealExamFault.State.FINISH.equals(refState)) { // 是否最后一次读取。
-                sm2 = send(sm1, seat, sim, RETRY_COUNT_READ_ONE_RESISTANCE, SLEEP_SHORT);
+                sm2 = send(sm1, seat, sim, RETRY_COUNT_READ_ONE_RESISTANCE, commStrategy.getSleepShort());
             } else {
-                sm2 = send(sm1, seat, sim, RETRY_COUNT_0, SLEEP_SHORT);
+                sm2 = send(sm1, seat, sim, RETRY_COUNT_0, commStrategy.getSleepShort());
             }
         } else {
-            sm2 = send(sm1, seat, sim, RETRY_COUNT_READ_ONE_RESISTANCE, SLEEP_SHORT);
+            sm2 = send(sm1, seat, sim, RETRY_COUNT_READ_ONE_RESISTANCE, commStrategy.getSleepShort());
         }
         simReceiveService.setFaultAnswerValue(sm2, sim, reF, f, refState);
     }
 
-    private long previousSendSleep = 0;
-
     /**
+     * 最基本的通信方法。
      * send hex message
+     * <p>
+     * 去掉synchronized
      *
      * @param sm              发送
      * @param seat            不能为空
@@ -767,7 +773,7 @@ public class CommSendService {
      * @param sleep           不使用传入0,不进行挂起。
      * @return
      */
-    public synchronized SimMsg send(final SimMsg sm, final Seat seat, final Sim sim, final int retryTotalCount, final long sleep) {
+    public SimMsg send(final SimMsg sm, final Seat seat, final Sim sim, final int retryTotalCount, final long sleep) {
         try {
             if (!config.isCommGlobal()) {
                 l.warn("isCommGlobal == false [模拟器通信被禁用!]");
@@ -787,20 +793,26 @@ public class CommSendService {
             {
                 l.info("####发送#### == Seat[{}],SimMsg[{}]", seat, sm);
             }
-            // 如果没有打开socket,顺道打开。正好后面要sleep
-            // SocketOldService实现
-            // socketOldService.openSocket();
-            socketService.openOne(seat.toSimSocketVo());
+            // 如果没有打开socket,顺道打开。正好后面要sleep。
+            // 不强制重开Socket。
+            // 先进行Socket相关处理。
+            SimSocketParamVo sspv = seat.toSimSocketParamVo();
+            socketService.openOne(sspv, socketService.isNotOk(sspv));
+            // Socket情况不正确,直接返回。
+            if (socketService.isNotOk(sspv)) {
+                sm.setResult(SimMsg.Result.SOCKET_CONNECT_EXCEPTION);
+                return sm;
+            }
             {
                 // sleep挂起线程,追求顺序请求。
-                if (sleep > 0 && previousSendSleep != 0L) {
-                    Thread.sleep(previousSendSleep);
+                // 大于0才挂起。
+                if (sleep > 0 && socketService.get(sspv).getPreviousSendSleep() > 0L) {
+                    // 时间间隔挂起。
+                    Thread.sleep(socketService.get(sspv).getPreviousSendSleep());
                 }
             }
-            previousSendSleep = sleep;
-            // SocketOldService实现
-            // Socket socket = socketOldService.getCachedSocket();
-            Socket socket = socketService.get(seat);
+            socketService.get(sspv).setPreviousSendSleep(sleep);
+            Socket socket = socketService.get(sspv).getSocket();
             InputStream is = socket.getInputStream();
             OutputStream os = socket.getOutputStream();
             os.write(hexStrToByteArrs(sm.getSendMsg()));
@@ -810,7 +822,7 @@ public class CommSendService {
             }
             byte[] buffer = new byte[LENGTH_24];
             int length = is.read(buffer);
-            StringBuffer sbHex = new StringBuffer();
+            StringBuilder sbHex = new StringBuilder();
             for (int i = 0; i < length; i++) {
                 sbHex.append(String.format("%02X", buffer[i]));
             }
@@ -838,25 +850,22 @@ public class CommSendService {
             // 最后返回报文实体。
             return sm;
         } catch (InterruptedException | IOException e) {
-            l.error("SocketTimeoutException");// SocketTimeoutException
-            e.printStackTrace();
-            sm.setResult(SimMsg.Result.SOCKET_EXCEPTION);
+            // SocketTimeoutException
+            l.error("SocketTimeoutException");
+            // e.printStackTrace();
+            sm.setResult(SimMsg.Result.SOCKET_TIMEOUT_EXCEPTION);
             if (sim != null) {
                 l.info("fail sim.getSimId() = {}", sim.getSimId());
             }
-            // SocketOldService实现
-            // boolean limit = socketOldService.commFailCountAdd1(Objects.requireNonNull(sim).getSimId());
-            SimSocketVo ssv = seat.toSimSocketVo();
-            // 失败计数
-            failedCountService.plus1(ssv);
-            if (failedCountService.isReachedMax(ssv, retryTotalCount)) {
+            SimSocketParamVo sspv = seat.toSimSocketParamVo();
+            // Socket失败计数
+            socketService.failedPlus1(sspv);
+            if (socketService.failedIsReachedMax(sspv, SocketService.SOCKET_CONNECT_RETRY_COUNT_LIMIT)) {
                 // 达到重试次数上限,认为模拟器离线
                 if (sim != null) {
                     simService.updateSimStateBySimId(sim.getSimId(), Sim.State.OFFLINE);
                 }
-                // SocketOldService实现
-                // socketOldService.commFailCountClearOne(sim.getSimId());
-                failedCountService.reset0(ssv);
+                socketService.failedReset0(sspv);
             }
             // 先考虑一台模拟器演示。
             // 进行重试 start

+ 48 - 0
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommStrategy.java

@@ -0,0 +1,48 @@
+package com.ruoyi.sim.service.impl;
+
+import org.springframework.stereotype.Service;
+
+@Service
+public class CommStrategy {
+
+    private boolean isLAN = true;
+
+    /**
+     * 请求间隔睡眠时间-long
+     * default:200L
+     */
+    private static final Long SLEEP_LONG = 300L;
+
+    private static final Long SLEEP_LONG_WAN = 3000L;
+
+    /**
+     * 请求间隔睡眠时间-mid
+     * default:100L
+     */
+    private static final Long SLEEP_MID = 1000L;
+
+    /**
+     * 请求间隔睡眠时间-short
+     * default:64L
+     */
+    private static final Long SLEEP_SHORT = 200L;
+
+    private static final Long SLEEP_SHORT_WAN = 2000L;
+
+
+    public Long getSleepLong() {
+        if (isLAN) {
+            return SLEEP_LONG;
+        } else {
+            return SLEEP_LONG_WAN;
+        }
+    }
+
+    public Long getSleepShort() {
+        if (isLAN) {
+            return SLEEP_SHORT;
+        } else {
+            return SLEEP_SHORT_WAN;
+        }
+    }
+}

+ 0 - 62
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/FailedCountService.java

@@ -1,62 +0,0 @@
-package com.ruoyi.sim.service.impl;
-
-import com.ruoyi.sim.domain.vo.SimSocketVo;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Service;
-
-import java.util.HashMap;
-import java.util.concurrent.atomic.AtomicInteger;
-
-@Service
-public class FailedCountService {
-
-    private static final Logger l = LoggerFactory.getLogger(FailedCountService.class);
-
-    private static final int COUNT_0 = 0;
-    private static final int COUNT_ADD_1 = 1;
-    private static final int INIT_SIZE = 16;
-    private static HashMap<String, AtomicInteger> failedMap = new HashMap<>(INIT_SIZE);
-
-    /**
-     * @param key
-     * @param limit include limit
-     * @return
-     */
-    public boolean isReachedMax(final SimSocketVo ssv, final int limit) {
-        final String key = ssv.toKey();
-        return (failedMap.containsKey(key) && failedMap.get(key).get() >= limit);
-    }
-
-    public int plus1(final SimSocketVo ssv) {
-        final String key = ssv.toKey();
-        if (!failedMap.containsKey(key)) {
-            failedMap.put(key, new AtomicInteger(COUNT_ADD_1));
-        } else {
-            failedMap.get(key).addAndGet(COUNT_ADD_1);
-        }
-        return failedMap.get(key).get();
-    }
-
-    public int get(final SimSocketVo ssv) {
-        final String key = ssv.toKey();
-        if (failedMap.containsKey(key)) {
-            return failedMap.get(key).get();
-        } else {
-            return COUNT_0;
-        }
-    }
-
-    public void reset0(final SimSocketVo ssv) {
-        final String key = ssv.toKey();
-        if (failedMap.containsKey(key)) {
-            failedMap.get(key).set(COUNT_0);
-        }
-    }
-
-    public void resetAll() {
-        for (String key : failedMap.keySet()) {
-            failedMap.remove(key);
-        }
-    }
-}

+ 56 - 14
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/RealExamCollectionService.java

@@ -289,6 +289,7 @@ public class RealExamCollectionService extends Ele6RYBaseService {
     @Transactional
     public AjaxResult open(final Long examCollectionId, final String examCollectionType) {
         l.debug("open examCollectionId= {}", examCollectionId);
+        l.debug("open examCollectionType= {}", examCollectionType);
         // check 1:检查id有效。
         RealExamCollection rec = selectRealExamCollectionByExamCollectionId(examCollectionId);
         if (rec == null) {
@@ -313,17 +314,35 @@ public class RealExamCollectionService extends Ele6RYBaseService {
         // check datetime todo:时间到了
         // do.
 
-        // Step 1:强制停掉所有的自主练习
-        {
-            // closeAllType(RealExamCollection.Type.SELF_EXERCISE);
-        }
-        // Step 2:强制停掉所有的练习
-        {
-            // closeAllType(RealExamCollection.Type.EXERCISE);
-        }
-        // Step 3:强制停掉 除本考试外的 所有考试
-        {
-            // closeAllExamExcludeId(rec.getExamCollectionId());
+
+        // 自然人电子税务局
+        // 年报 多次  汇总表   12366
+
+        switch (examCollectionType) {
+            case RealExamCollection.Type.EXERCISE: {
+                if (existOpenedByType(RealExamCollection.Type.EXAM)) {
+                    return AjaxResult.error("存在已经打开的考试,请关闭后再操作!");
+                }
+                closeAllExcludeIdByType(RealExamCollection.Type.EXERCISE, rec.getExamCollectionId());
+                closeAllByType(RealExamCollection.Type.SELF_EXERCISE);
+                break;
+            }
+            case RealExamCollection.Type.SELF_EXERCISE: {
+                if (existOpenedByType(RealExamCollection.Type.EXAM)) {
+                    return AjaxResult.error("存在已经打开的考试,请关闭后再操作!");
+                }
+                if (existOpenedByType(RealExamCollection.Type.EXERCISE)) {
+                    return AjaxResult.error("存在已经打开的训练,请关闭后再操作!");
+                }
+                // 练习可以同时打开多个。
+                break;
+            }
+            case RealExamCollection.Type.EXAM: {
+                closeAllByType(RealExamCollection.Type.EXERCISE);
+                closeAllByType(RealExamCollection.Type.SELF_EXERCISE);
+                closeAllExcludeIdByType(RealExamCollection.Type.EXAM, rec.getExamCollectionId());
+                break;
+            }
         }
         // Step 4:尝试打开所有Socket,提前准备,允许有打开失败的
         // SocketOldService实现。
@@ -361,6 +380,14 @@ public class RealExamCollectionService extends Ele6RYBaseService {
         return (selectRealExamCollectionOpened() != null);
     }
 
+    public boolean existOpenedByType(String examCollectionType) {
+        RealExamCollection q = new RealExamCollection();
+        q.setExamCollectionType(examCollectionType);
+        q.setExamCollectionState(RealExamCollection.State.OPENED);
+        List<RealExamCollection> list = selectRealExamCollectionList(q);
+        return (!list.isEmpty());
+    }
+
     public RealExamCollection selectRealExamCollectionOpened() {
         RealExamCollection q = new RealExamCollection();
         q.setExamCollectionState(RealExamCollection.State.OPENED);
@@ -396,10 +423,19 @@ public class RealExamCollectionService extends Ele6RYBaseService {
     public AjaxResult closeAll() {
         // SocketOldService实现
         // return socketOldService.closeSocket();
+
+        closeAllByType(RealExamCollection.Type.EXERCISE);
+        closeAllByType(RealExamCollection.Type.SELF_EXERCISE);
+        closeAllByType(RealExamCollection.Type.EXAM);
         return AjaxResult.success();
     }
 
-    private void closeAllType(final String type) {
+    /**
+     * 强制停掉所有的
+     *
+     * @param type
+     */
+    private void closeAllByType(final String type) {
         RealExamCollection q = new RealExamCollection();
         q.setExamCollectionType(type);
         selectRealExamCollectionList(q)
@@ -409,8 +445,14 @@ public class RealExamCollectionService extends Ele6RYBaseService {
                 });
     }
 
-    private void closeAllExamExcludeId(final Long excludeRecId) {
-        List<RealExamCollection> list = listAllByType(RealExamCollection.Type.EXAM);
+    /**
+     * 强制停掉 除本type外的 所有的type
+     *
+     * @param type
+     * @param excludeRecId
+     */
+    private void closeAllExcludeIdByType(final String type, final Long excludeRecId) {
+        List<RealExamCollection> list = listAllByType(type);
         for (RealExamCollection ec : list) {
             if (ec.getExamCollectionId().equals(excludeRecId)) {
                 // 跳过本考试。

+ 26 - 14
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/RealExamService.java

@@ -306,7 +306,9 @@ public class RealExamService {
             // l.info("fake re = {}", re);
         }
         // check id data.
-        // Step :检查参数有效性。
+        // Step :检查参数examId有效性
+        // Step :检查参数studentBindIp有效性
+        // Step :检查参数examCollectionType有效性
         {
             AjaxResult ar01 = checkExamId(examId);
             if (ar01.isError()) {
@@ -321,11 +323,12 @@ public class RealExamService {
         Seat seat = seatService.uniqueByBindIp(studentBindIp);
         {
             if (seat == null) {
+
                 throw new IllegalArgumentException("XXX");
             }
         }
         // Step :ping通 路由器。
-        {
+        if (false) {
             AjaxResult ar = commCheckService.checkRouterState(simConfig.getRouterIp());
             if (ar.isError()) {
                 return ar;
@@ -339,7 +342,7 @@ public class RealExamService {
 //            }
         }
         // Step :ping通 RS485。
-        {
+        if (false) {
             AjaxResult ar = commCheckService.checkPingRs485State(seat.getSeatRs485Ip());
             if (ar.isError()) {
                 // todo:重复
@@ -354,7 +357,7 @@ public class RealExamService {
         }
         // Step :如果有缓存Socket并且可用,使用缓存Socket,检查并建立Socket连接;否则返回对应错误。
         {
-            AjaxResult ar = socketService.openOne(seat.toSimSocketVo());
+            AjaxResult ar = socketService.openOne(seat.toSimSocketParamVo(), true);
             if (ar.isError()) {
                 return ar;
             }
@@ -386,8 +389,8 @@ public class RealExamService {
         }
         Sim sim = simService.selectSimBySimId(re.getSimId());
         // 检查模拟器类型
+        final String targetSimType = re.getSimType();
         {
-            String targetSimType = re.getSimType();
             AjaxResult ar = commCheckService.checkOneSimType(seat, true, targetSimType);
             if (ar.isError()) {
                 return ar;
@@ -400,27 +403,27 @@ public class RealExamService {
 //                return arE3;
 //            }
         }
-        // Step 7:可换件检查,读取对应一台模拟器 所有故障部位值。检查模拟器所有的 真实的 故障部位 是否异常 或者 空值。特殊的故障部位要单独判断。
+        // Step :可换件检查,读取对应一台模拟器 所有故障部位值。检查模拟器所有的 真实的 故障部位 是否异常 或者 空值。特殊的故障部位要单独判断。
         if (SimDebugConfig.CHECK_REPLACE_EMPTY) {
-            AjaxResult arE2 = commSendService.readOneSimAllFaultCheck(seat, sim);
-            if (arE2.isError()) {
-                return arE2;
+            AjaxResult ar = commSendService.readOneSimAllFaultCheck(seat, sim);
+            if (ar.isError()) {
+                return ar;
             }
         }
-        // Step 8:清除对应一台模拟器 所有 真实的 故障部位故障。
+        // Step :清除对应一台模拟器 所有 真实的 故障部位故障。
         {
             commSendService.clearOneSimAllFaultByExam(re);
         }
-        // Step 9:下发对应一台模拟器 出题选中的 故障位置故障。
+        // Step :下发对应一台模拟器 出题选中的 故障位置故障。
         {
             commSendService.writeOneSimAllSelectFaultByExam(re);
         }
-        // Step 10:读取对应一台模拟器 所有的 真实的 故障部位 电阻值代表值 作为出题值。
+        // Step :读取对应一台模拟器 所有的 真实的 故障部位 电阻值代表值 作为出题值。
         // 修改关联状态
         {
             commSendService.readOneSimAllFaultFirstTimeByExam(re);
         }
-        // Step 11:修改当前exam_id状态。
+        // Step :修改当前exam_id考试数据的状态。
         if (realExamFaultService.isType2ExamPrepareStartOk(re.getExamId())) {
             updateOneState(re.getExamId(), RealExam.State.SIM_PREPARE_OK);
             updateOneState(re.getExamId(), RealExam.State.ANSWERING);
@@ -525,12 +528,16 @@ public class RealExamService {
      * @return RealExam
      */
     @Transactional
-    public AjaxResult studentSubmitRealExam(Long examId) {
+    public AjaxResult studentSubmitRealExam(final Long examId, final String studentBindIp, final String examCollectionType) {
         RealExam re = selectRealExamByExamId(examId);
         {
             // todo:delete
             // re.setSimId(getFakeSimId(re));
         }
+        // Step :检查参数examId有效性
+        // Step :检查参数studentBindIp有效性
+        // Step :检查参数examCollectionType有效性
+
         // check part.
         {
             AjaxResult arE1 = checkExamId(examId);
@@ -540,6 +547,11 @@ public class RealExamService {
         }
         // 检查一下模拟器状态。
         Seat seat = seatService.selectSeatBySeatId(re.getSeatId());
+
+        // 检查换学生端交卷的情况。
+
+        //
+
         // 如果模拟器离线
         {
             // AjaxResult arE3 = commSendService.checkOneSimStateActive(seat);

+ 9 - 2
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/SeatService.java

@@ -12,6 +12,9 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.ruoyi.sim.mapper.SeatMapper;
 import com.ruoyi.sim.domain.Seat;
+import org.springframework.transaction.annotation.Isolation;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
 
 /**
  * 座Service业务层处理
@@ -106,7 +109,11 @@ public class SeatService {
 
     public List<Seat> listAllEnable() {
         List<Seat> list = new ArrayList<>();
-        seatMapper.selectSeatList(new Seat()).stream().filter(Objects::nonNull).filter(s -> !StringUtils.equals(Seat.SocketState.DISABLE, s.getSeatRs485SocketState())).forEach(list::add);
+        seatMapper.selectSeatList(new Seat())
+                .stream()
+                .filter(Objects::nonNull)
+                .filter(s -> !StringUtils.equals(Seat.SocketState.DISABLE, s.getSeatRs485SocketState()))
+                .forEach(list::add);
         return list;
     }
 
@@ -203,7 +210,7 @@ public class SeatService {
         q.setSeatRs485Ip(rs485Ip);
         selectSeatList(q).forEach(seat -> {
             seat.setSeatRs485SocketState(socketState);
-            seatMapper.updateSeat(seat);
+            updateSeat(seat);
         });
     }
 }

+ 3 - 1
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/SimService.java

@@ -14,6 +14,8 @@ import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import com.ruoyi.sim.mapper.SimMapper;
 import com.ruoyi.sim.domain.Sim;
+import org.springframework.transaction.annotation.Isolation;
+import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
 /**
@@ -216,7 +218,7 @@ public class SimService {
         return !Sim.STATE_SET.contains(simState);
     }
 
-    @Transactional
+    @Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.SERIALIZABLE)
     public int updateSimStateBySimId(final Long simId, final String simState) {
         // check
         if (checkState(simState)) {

+ 2 - 0
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/SocketOldService.java

@@ -2,6 +2,7 @@ package com.ruoyi.sim.service.impl;
 
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.sim.config.SimConfig;
+import jdk.jfr.Description;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -15,6 +16,7 @@ import static com.ruoyi.sim.constant.CommConst.OFFLINE_LIMIT;
 import static com.ruoyi.sim.constant.CommConst.SOCKET_TIME_OUT;
 
 @Service
+@Deprecated
 public class SocketOldService {
 
     private static final Logger l = LoggerFactory.getLogger(SocketOldService.class);

+ 119 - 43
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/SocketService.java

@@ -3,29 +3,45 @@ package com.ruoyi.sim.service.impl;
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.sim.config.SimConfig;
 import com.ruoyi.sim.domain.Seat;
-import com.ruoyi.sim.domain.vo.SimSocketVo;
-import com.ruoyi.sim.domain.vo.SocketWrapValue;
+import com.ruoyi.sim.domain.vo.SimSocketParamVo;
+import com.ruoyi.sim.domain.vo.SocketWrapCacheVo;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.parameters.P;
 import org.springframework.stereotype.Service;
 
 import java.io.IOException;
 import java.net.Socket;
 import java.util.HashMap;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import static com.ruoyi.sim.constant.CommConst.SOCKET_TIME_OUT;
 
 /**
  * 1.所有Socket常开。
  * todo: connectedTimeMillis 时间。
+ * <p>
+ * 创建Socket重试,用failed开始方法去操作。
  */
 @Service
 public class SocketService {
 
     private static final Logger l = LoggerFactory.getLogger(SocketService.class);
 
+    /**
+     * 硬件孙总北京办公室,测试远程地址
+     * <p>
+     * 孙总办公室域名
+     * nas.yichiot.com
+     */
+    public static final String IP_TEST = "221.218.213.170";
+
+    public static final int PORT_TEST = 8899;
+
+    private static final int LOCAL_PORT = 9000;
+
     private static final int INIT_SIZE = 32;
     /**
      * 6 hours
@@ -34,25 +50,25 @@ public class SocketService {
      */
     private static final long TIMEOUT_LIMIT = 1000L * 60 * 60 * 6;
 
+    public static final int SOCKET_CONNECT_RETRY_COUNT_LIMIT = 4;
+
     /**
      * key: ip:port
      * value:
      */
-    private static HashMap<String, SocketWrapValue> cachedMap = new HashMap<>(INIT_SIZE);
+    private static HashMap<String, SocketWrapCacheVo> cachedMap = new HashMap<>(INIT_SIZE);
 
     @Autowired
     private SimConfig config;
     @Autowired
-    private FailedCountService failedCountService;
-    @Autowired
     private SeatService seatService;
 
     /**
-     * @param ssv
+     * @param sspv
      * @return true:socket ok!
      */
-    public boolean isOk(final SimSocketVo ssv) {
-        final String key = ssv.toKey();
+    public boolean isOk(final SimSocketParamVo sspv) {
+        final String key = sspv.toKey();
         if (cachedMap.containsKey(key) && cachedMap.get(key) != null) {
             Socket s = cachedMap.get(key).getSocket();
             if (s != null) {
@@ -62,8 +78,8 @@ public class SocketService {
         return false;
     }
 
-    public boolean isNotOk(final SimSocketVo ssv) {
-        return !isOk(ssv);
+    public boolean isNotOk(final SimSocketParamVo sspv) {
+        return !isOk(sspv);
     }
 
     /**
@@ -73,7 +89,7 @@ public class SocketService {
      * @param ssv
      * @return
      */
-    public boolean isTimeout(SimSocketVo ssv) {
+    public boolean isTimeout(SimSocketParamVo ssv) {
         if (cachedMap.containsKey(ssv.toKey())) {
             Long cached = cachedMap.get(ssv.toKey()).getOkTimeMillis();
             if (cached == null || cached == 0L) {
@@ -85,10 +101,11 @@ public class SocketService {
     }
 
     /**
-     * @param ssv
+     * @param sspv
+     * @param force 是否强制使用新连接的Socket
      * @return
      */
-    public AjaxResult openOne(final SimSocketVo ssv) {
+    public AjaxResult openOne(final SimSocketParamVo sspv, final boolean force) {
         // check.
         if (!config.isCommGlobal()) {
             l.warn("isCommGlobal == {} [模拟器通信被禁用!]", config.isCommGlobal());
@@ -96,26 +113,37 @@ public class SocketService {
         }
         //
         try {
-            if (isNotOk(ssv)) {
-                final String key = ssv.toKey();
-                l.info("openSocket cachedSocket is not ok!try new socket ip = {}:{}!", ssv.getIp(), ssv.getPort());
-                closeOne(ssv);
-                Socket s = new Socket(ssv.getIp(), ssv.getPort());
+            if (isNotOk(sspv) || force) {
+                final String key = sspv.toKey();
+                l.info("openSocket cachedSocket is not ok!try new socket ip = {}:{}!forceNew = {}", sspv.getIp(), sspv.getPort(), force);
+                closeOne(sspv);
+                // todo: LOCAL_PORT
+                Socket s = new Socket(sspv.getIp(), sspv.getPort());
                 s.setSoTimeout(SOCKET_TIME_OUT);
-                SocketWrapValue value = new SocketWrapValue(ssv.getIp(), ssv.getPort(), s, System.currentTimeMillis());
+                SocketWrapCacheVo value = new SocketWrapCacheVo(sspv.getIp(), sspv.getPort(), s, System.currentTimeMillis());
                 cachedMap.put(key, value);
-                // failed count reset.
-                failedCountService.reset0(ssv);
+                // socket failed count reset.
+                failedReset0(sspv);
             } else {
-                l.info("openSocket cachedSocket cache ok!cached socket ip = {}:{}!", ssv.getIp(), ssv.getPort());
+                l.info("openSocket cachedSocket cache ok!cached socket ip = {}:{}!forceNew = {}", sspv.getIp(), sspv.getPort(), force);
             }
-            Seat seat = seatService.uniqueByRs485IpAndPort(ssv.getIp(), ssv.getPort());
+            Seat seat = seatService.uniqueByRs485IpAndPort(sspv.getIp(), sspv.getPort());
             seat.setSeatRs485SocketState(Seat.SocketState.ONLINE);
             seatService.updateSeat(seat);
-            return AjaxResult.success("Socket[" + ssv.getIp() + ":" + ssv.getPort() + "],创建成功!");
+            return AjaxResult.success("Socket[" + sspv.getIp() + ":" + sspv.getPort() + "],创建成功!");
         } catch (IOException e) {
-            l.error(ssv.toString());
-            return AjaxResult.error("Socket[" + ssv.getIp() + ":" + ssv.getPort() + "],创建失败!");
+            l.error("IOException = {}", sspv);
+            if (failedIsReachedMax(sspv, SOCKET_CONNECT_RETRY_COUNT_LIMIT)) {
+                return AjaxResult.error("Socket[" + sspv.getIp() + ":" + sspv.getPort() + "],重试[" + failedGet(sspv) + "]次,创建失败!");
+            } else {
+                failedPlus1(sspv);
+                AjaxResult ar = openOne(sspv, force);
+                if (ar.isSuccess()) {
+                    return ar;
+                } else {
+                    return AjaxResult.error("Socket[" + sspv.getIp() + ":" + sspv.getPort() + "],进行重试,创建失败!");
+                }
+            }
         }
     }
 
@@ -131,18 +159,19 @@ public class SocketService {
         }
         List<Seat> allSeat = seatService.listAllEnable();
         for (Seat s : allSeat) {
-            openOne(s.toSimSocketVo());
+            AjaxResult ar = openOne(s.toSimSocketParamVo(), false);
+            l.debug("AjaxResult = {}", ar);
         }
         return AjaxResult.success("所有Socket,创建成功!");
     }
 
-    public AjaxResult closeOne(final SimSocketVo ssv) {
+    public AjaxResult closeOne(final SimSocketParamVo sspv) {
         if (!config.isCommGlobal()) {
             l.warn("isCommGlobal == {} [模拟器通信被禁用!]", config.isCommGlobal());
             return AjaxResult.error("模拟器通信被禁用!");
         }
         String msgOk = "关闭Socket成功!";
-        final String key = ssv.toKey();
+        final String key = sspv.toKey();
         try {
             if (cachedMap.containsKey(key)) {
                 Socket s = cachedMap.get(key).getSocket();
@@ -153,9 +182,9 @@ public class SocketService {
         } catch (IOException e) {
             e.printStackTrace();
         } finally {
-            cachedMap.remove(key);
             // failed count reset.
-            failedCountService.reset0(ssv);
+            failedReset0(sspv);
+            cachedMap.remove(key);
             return AjaxResult.success(msgOk);
         }
     }
@@ -168,34 +197,81 @@ public class SocketService {
         final String msgOk = "关闭所有Socket成功!";
         List<Seat> allSeat = seatService.listAllEnable();
         for (Seat s : allSeat) {
-            closeOne(new SimSocketVo(s.getSeatRs485Ip(), s.getSeatRs485Port()));
+            closeOne(new SimSocketParamVo(s.getSeatRs485Ip(), s.getSeatRs485Port()));
         }
-        failedCountService.resetAll();
         return AjaxResult.success(msgOk);
     }
 
-    public Socket get(final Seat seat) {
+    /**
+     * @param seat
+     * @return todo:null
+     */
+    public SocketWrapCacheVo get(final Seat seat) {
         if (seat == null) {
-            throw new IllegalArgumentException("seat is null");
+            throw new IllegalArgumentException("seat为空。");
         }
-        return get(new SimSocketVo(seat.getSeatRs485Ip(), seat.getSeatRs485Port()));
+        return get(new SimSocketParamVo(seat.getSeatRs485Ip(), seat.getSeatRs485Port()));
     }
 
     /**
-     * @param ssv
+     * @param sspv
      * @return
      */
-    public Socket get(final SimSocketVo ssv) {
-        if (isNotOk(ssv)) {
-            openOne(ssv);
+    public SocketWrapCacheVo get(final SimSocketParamVo sspv) {
+        if (isNotOk(sspv)) {
+            AjaxResult ar = openOne(sspv, true);
+            if (ar.isError()) {
+                // todo: isError
+            }
         }
-        return cachedMap.get(ssv.toKey()).getSocket();
+        return cachedMap.get(sspv.toKey());
+    }
+
+    /**
+     * 初始化。todo:
+     */
+    public void clear(final SimSocketParamVo sspv) {
+
     }
 
+    private static final int SOCKET_FAILED_COUNT_0 = 0;
+    private static final int SOCKET_FAILED_COUNT_ADD_1 = 1;
+
     /**
-     * 初始化。
+     * @param sspv
+     * @param limit include limit
+     * @return
      */
-    public void resetAll() {
+    public boolean failedIsReachedMax(final SimSocketParamVo sspv, final int limit) {
+        final String key = sspv.toKey();
+        return (cachedMap.containsKey(key) && cachedMap.get(key).getFailedCount().get() >= limit);
+    }
+
+    public int failedPlus1(final SimSocketParamVo sspv) {
+        final String key = sspv.toKey();
+        if (!cachedMap.containsKey(key)) {
+            cachedMap.get(key).setFailedCount(new AtomicInteger(SOCKET_FAILED_COUNT_ADD_1));
+        } else {
+            cachedMap.get(key).getFailedCount().addAndGet(SOCKET_FAILED_COUNT_ADD_1);
+        }
+        return cachedMap.get(key).getFailedCount().get();
+    }
 
+    public int failedGet(final SimSocketParamVo sspv) {
+        final String key = sspv.toKey();
+        if (cachedMap.containsKey(key)) {
+            return cachedMap.get(key).getFailedCount().get();
+        } else {
+            return SOCKET_FAILED_COUNT_0;
+        }
+    }
+
+    public void failedReset0(final SimSocketParamVo sspv) {
+        final String key = sspv.toKey();
+        if (cachedMap.containsKey(key)) {
+            cachedMap.get(key).getFailedCount().set(SOCKET_FAILED_COUNT_0);
+        } else {
+            l.debug("not containsKey SimSocketParamVo sspv:" + sspv);
+        }
     }
 }

+ 2 - 1
ruoyi-ui/vue.config.js

@@ -35,8 +35,9 @@ module.exports = {
     proxy: {
       // detail: https://cli.vuejs.org/config/#devserver-proxy
       [process.env.VUE_APP_BASE_API]: {
+        // target: `http://47.104.188.84:8093`,
         target: `http://localhost:8080`,
-        // target: `http://120.46.205.190:8080/`,
+        // target: `http://192.168.1.60:8080/`,
         changeOrigin: true,
         pathRewrite: {
           ['^' + process.env.VUE_APP_BASE_API]: ''