1
0

5 Commits 6224c338e4 ... b3151b2277

Autor SHA1 Nachricht Datum
  tom b3151b2277 新Socket改版后的问题解决。 vor 9 Monaten
  tom 523a0d54ff 修复模拟器1型10数据错误。 vor 9 Monaten
  tom 2e0fdf632a 删除SQL。 vor 10 Monaten
  tom d0ab65aace 万能询问报文 vor 10 Monaten
  tom cd244520f2 studentRefreshSimState vor 10 Monaten
30 geänderte Dateien mit 652 neuen und 6952 gelöschten Zeilen
  1. 34 17
      pla-sim/01_SQL/02_table/mx_debug_fault.sql
  2. 18 18
      pla-sim/01_SQL/02_table/mx_seat.sql
  3. 36 36
      pla-sim/01_SQL/02_table/mx_sim.sql
  4. 8 8
      pla-sim/01_SQL/02_table/sim_seat.sql
  5. 7 7
      pla-sim/01_SQL/02_table/sim_sim.sql
  6. 0 1676
      pla-sim/01_SQL/03_dev_backup/pla-chem-sim-dev-1.sql
  7. 0 4898
      pla-sim/01_SQL/04_dev_backup_47-104-188-84/pla-chem-sim-dev-1.sql
  8. 0 16
      ruoyi-sim/src/main/java/com/ruoyi/sim/constant/CommConst.java
  9. 17 10
      ruoyi-sim/src/main/java/com/ruoyi/sim/controller/HardwareCommDebugController.java
  10. 11 3
      ruoyi-sim/src/main/java/com/ruoyi/sim/controller/RealExamController.java
  11. 10 4
      ruoyi-sim/src/main/java/com/ruoyi/sim/controller/TestIotController.java
  12. 9 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/domain/RealExamCollection.java
  13. 3 3
      ruoyi-sim/src/main/java/com/ruoyi/sim/domain/Seat.java
  14. 3 2
      ruoyi-sim/src/main/java/com/ruoyi/sim/domain/SimMsg.java
  15. 52 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/domain/vo/SeatVo.java
  16. 10 4
      ruoyi-sim/src/main/java/com/ruoyi/sim/domain/vo/SimSocketParamVo.java
  17. 108 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/domain/vo/SocketWrapCacheVo.java
  18. 0 62
      ruoyi-sim/src/main/java/com/ruoyi/sim/domain/vo/SocketWrapValue.java
  19. 4 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommBuildService.java
  20. 7 10
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommCheckService.java
  21. 50 41
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommSendService.java
  22. 48 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommStrategy.java
  23. 0 62
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/FailedCountService.java
  24. 56 14
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/RealExamCollectionService.java
  25. 26 14
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/RealExamService.java
  26. 9 2
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/SeatService.java
  27. 3 1
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/SimService.java
  28. 2 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/SocketOldService.java
  29. 119 43
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/SocketService.java
  30. 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;

+ 18 - 18
pla-sim/01_SQL/02_table/mx_seat.sql

@@ -1,17 +1,17 @@
 /*
  Navicat Premium Dump SQL
 
- Source Server         : 47.104.188.84-sim
+ Source Server         : fhxy-192.168.1.61-polardbx
  Source Server Type    : MySQL
- Source Server Version : 80020 (8.0.20)
- Source Host           : 47.104.188.84:65006
- Source Schema         : pla-chem-sim-dev-1
+ Source Server Version : 80032 (8.0.32-X-Cluster-8.4.19-20241112)
+ Source Host           : 192.168.1.61:4886
+ Source Schema         : pla-chem-sim-dev-2
 
  Target Server Type    : MySQL
- Target Server Version : 80020 (8.0.20)
+ Target Server Version : 80032 (8.0.32-X-Cluster-8.4.19-20241112)
  File Encoding         : 65001
 
- Date: 12/03/2025 16:30:24
+ Date: 21/03/2025 15:47:09
 */
 
 SET NAMES utf8mb4;
@@ -26,8 +26,8 @@ CREATE TABLE `mx_seat`  (
   `seat_num` int NOT NULL DEFAULT 0 COMMENT '座号',
   `seat_bind_ip` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '[电脑]绑定的[IP地址]',
   `seat_rs485_ip` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '[RS485]绑定的[IP地址]',
-  `seat_rs485_port` int NOT NULL COMMENT '[RS485]绑定的[端口]',
-  `seat_rs485_socket_state` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'Socket状态:[0]:初始化,[1]:打开,[2]:关闭,[5]:禁用',
+  `seat_rs485_port` int NOT NULL DEFAULT 0 COMMENT '[RS485]绑定的[端口]',
+  `seat_rs485_socket_state` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT 'Socket状态:[0]:初始化,[1]:打开,[2]:关闭,[5]:禁用',
   `current_user_id` bigint NOT NULL DEFAULT 0 COMMENT '当前座上学员/用户ID',
   `current_sim_id` bigint NOT NULL DEFAULT 0 COMMENT '模拟器的ID:[0]没有连接任何模拟器,[xx]:具体某台模拟器',
   `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '创建者',
@@ -41,15 +41,15 @@ CREATE TABLE `mx_seat`  (
 -- ----------------------------
 -- Records of mx_seat
 -- ----------------------------
-INSERT INTO `mx_seat` VALUES (1, 1, '192.168.1.101', '192.168.1.201', 10001, '', 0, 0, NULL, NULL, NULL, NULL, '座号01');
-INSERT INTO `mx_seat` VALUES (2, 2, '192.168.1.102', '192.168.1.201', 10002, '', 0, 0, NULL, NULL, NULL, NULL, '座号02');
-INSERT INTO `mx_seat` VALUES (3, 3, '192.168.1.103', '192.168.1.201', 10003, '', 0, 0, NULL, NULL, NULL, NULL, '座号03');
-INSERT INTO `mx_seat` VALUES (4, 4, '192.168.1.104', '192.168.1.201', 10004, '', 0, 0, NULL, NULL, NULL, NULL, '座号04');
-INSERT INTO `mx_seat` VALUES (5, 5, '192.168.1.105', '192.168.1.201', 10008, '', 0, 0, NULL, NULL, NULL, NULL, '座号05');
-INSERT INTO `mx_seat` VALUES (6, 6, '192.168.1.106', '192.168.1.202', 11001, '', 0, 0, NULL, NULL, NULL, NULL, '座号06');
-INSERT INTO `mx_seat` VALUES (7, 7, '192.168.1.107', '192.168.1.202', 11002, '', 0, 0, NULL, NULL, NULL, NULL, '座号07');
-INSERT INTO `mx_seat` VALUES (8, 8, '192.168.1.108', '192.168.1.202', 11003, '', 0, 0, NULL, NULL, NULL, NULL, '座号08');
-INSERT INTO `mx_seat` VALUES (9, 9, '192.168.1.109', '192.168.1.202', 11004, '', 0, 0, NULL, NULL, NULL, NULL, '座号09');
-INSERT INTO `mx_seat` VALUES (10, 10, '192.168.1.110', '192.168.1.202', 11008, '', 0, 0, NULL, NULL, NULL, NULL, '座号10');
+INSERT INTO `mx_seat` VALUES (1, 1, '192.168.1.101', '192.168.1.201', 10001, '1', 0, 4, NULL, NULL, NULL, '2025-03-21 15:18:58', '座号01');
+INSERT INTO `mx_seat` VALUES (2, 2, '192.168.1.102', '192.168.1.201', 10002, '1', 0, 2, NULL, NULL, NULL, '2025-03-21 15:18:58', '座号02');
+INSERT INTO `mx_seat` VALUES (3, 3, '192.168.1.103', '192.168.1.201', 10003, '1', 0, 1, NULL, NULL, NULL, '2025-03-21 15:18:58', '座号03');
+INSERT INTO `mx_seat` VALUES (4, 4, '192.168.1.104', '192.168.1.201', 10004, '1', 0, 0, NULL, NULL, NULL, '2025-03-21 15:18:59', '座号04');
+INSERT INTO `mx_seat` VALUES (5, 5, '192.168.1.105', '192.168.1.201', 10008, '1', 0, 8, NULL, NULL, NULL, '2025-03-21 15:18:58', '座号05');
+INSERT INTO `mx_seat` VALUES (6, 6, '192.168.1.106', '192.168.1.202', 11001, '1', 0, 5, NULL, NULL, NULL, '2025-03-21 15:18:58', '座号06');
+INSERT INTO `mx_seat` VALUES (7, 7, '192.168.1.107', '192.168.1.202', 11002, '1', 0, 3, NULL, NULL, NULL, '2025-03-21 15:18:58', '座号07');
+INSERT INTO `mx_seat` VALUES (8, 8, '192.168.1.108', '192.168.1.202', 11003, '1', 0, 7, NULL, NULL, NULL, '2025-03-21 15:18:58', '座号08');
+INSERT INTO `mx_seat` VALUES (9, 9, '192.168.1.109', '192.168.1.202', 11004, '1', 0, 6, NULL, NULL, NULL, '2025-03-21 15:18:58', '座号09');
+INSERT INTO `mx_seat` VALUES (10, 10, '192.168.1.110', '192.168.1.202', 11008, '1', 0, 168, NULL, NULL, NULL, '2025-03-21 15:18:58', '座号10');
 
 SET FOREIGN_KEY_CHECKS = 1;

+ 36 - 36
pla-sim/01_SQL/02_table/mx_sim.sql

@@ -1,17 +1,17 @@
 /*
  Navicat Premium Dump SQL
 
- Source Server         : 47.104.188.84-sim
+ Source Server         : fhxy-192.168.1.61-polardbx
  Source Server Type    : MySQL
- Source Server Version : 80020 (8.0.20)
- Source Host           : 47.104.188.84:65006
- Source Schema         : pla-chem-sim-dev-1
+ Source Server Version : 80032 (8.0.32-X-Cluster-8.4.19-20241112)
+ Source Host           : 192.168.1.61:4886
+ Source Schema         : pla-chem-sim-dev-2
 
  Target Server Type    : MySQL
- Target Server Version : 80020 (8.0.20)
+ Target Server Version : 80032 (8.0.32-X-Cluster-8.4.19-20241112)
  File Encoding         : 65001
 
- Date: 12/03/2025 16:30:14
+ Date: 21/03/2025 15:46:59
 */
 
 SET NAMES utf8mb4;
@@ -41,35 +41,35 @@ CREATE TABLE `mx_sim`  (
 -- ----------------------------
 -- Records of mx_sim
 -- ----------------------------
-INSERT INTO `mx_sim` VALUES (1, 1, '0001', '2', '', '01', NULL, NULL, NULL, NULL, NULL, '2025-03-12 16:29:50', '');
-INSERT INTO `mx_sim` VALUES (2, 2, '0001', '2', '', '02', NULL, NULL, NULL, NULL, NULL, '2025-03-12 16:29:50', '');
-INSERT INTO `mx_sim` VALUES (3, 3, '0001', '2', '', '03', NULL, NULL, NULL, NULL, NULL, '2025-03-12 16:29:50', '');
-INSERT INTO `mx_sim` VALUES (4, 4, '0001', '2', '', '04', NULL, NULL, NULL, NULL, NULL, '2025-03-12 16:29:50', '');
-INSERT INTO `mx_sim` VALUES (5, 5, '0001', '2', '', '05', NULL, NULL, NULL, NULL, NULL, '2025-03-12 16:29:51', '');
-INSERT INTO `mx_sim` VALUES (6, 6, '0001', '2', '', '06', NULL, NULL, NULL, NULL, NULL, '2025-03-12 16:29:51', '');
-INSERT INTO `mx_sim` VALUES (7, 7, '0001', '2', '', '07', NULL, NULL, NULL, NULL, NULL, '2025-03-12 16:29:51', '');
-INSERT INTO `mx_sim` VALUES (8, 8, '0001', '2', '', '08', NULL, NULL, NULL, NULL, NULL, '2025-03-12 16:29:31', '');
-INSERT INTO `mx_sim` VALUES (9, 9, '0001', '2', '', '09', NULL, NULL, NULL, NULL, NULL, '2025-03-12 16:29:51', '');
-INSERT INTO `mx_sim` VALUES (10, 10, '0001', '2', '', '10', NULL, NULL, NULL, NULL, NULL, '2025-03-12 16:29:51', '');
-INSERT INTO `mx_sim` VALUES (81, 1, '0002', '2', '', '51', NULL, NULL, NULL, NULL, NULL, '2025-03-12 16:29:31', '');
-INSERT INTO `mx_sim` VALUES (82, 2, '0002', '2', '', '52', NULL, NULL, NULL, NULL, NULL, '2025-03-12 16:29:51', '');
-INSERT INTO `mx_sim` VALUES (83, 3, '0002', '2', '', '53', NULL, NULL, NULL, NULL, NULL, '2025-03-12 16:29:51', '');
-INSERT INTO `mx_sim` VALUES (84, 4, '0002', '2', '', '54', NULL, NULL, NULL, NULL, NULL, '2025-03-12 16:29:52', '');
-INSERT INTO `mx_sim` VALUES (85, 5, '0002', '2', '', '55', NULL, NULL, NULL, NULL, NULL, '2025-03-12 16:29:52', '');
-INSERT INTO `mx_sim` VALUES (86, 6, '0002', '2', '', '56', NULL, NULL, NULL, NULL, NULL, '2025-03-12 16:29:52', '');
-INSERT INTO `mx_sim` VALUES (87, 7, '0002', '2', '', '57', NULL, NULL, NULL, NULL, NULL, '2025-03-12 16:29:52', '');
-INSERT INTO `mx_sim` VALUES (88, 8, '0002', '2', '', '58', NULL, NULL, NULL, NULL, NULL, '2025-03-12 16:29:52', '');
-INSERT INTO `mx_sim` VALUES (89, 9, '0002', '2', '', '59', NULL, NULL, NULL, NULL, NULL, '2025-03-12 16:29:52', '');
-INSERT INTO `mx_sim` VALUES (90, 10, '0002', '2', '', '5A', NULL, NULL, NULL, NULL, NULL, '2025-03-12 16:29:52', '');
-INSERT INTO `mx_sim` VALUES (161, 1, '0003', '2', '', 'A1', NULL, NULL, NULL, NULL, NULL, '2025-03-12 16:29:22', '');
-INSERT INTO `mx_sim` VALUES (162, 2, '0003', '2', '', 'A2', NULL, NULL, NULL, NULL, NULL, '2025-03-12 16:29:52', '');
-INSERT INTO `mx_sim` VALUES (163, 3, '0003', '2', '', 'A3', NULL, NULL, NULL, NULL, NULL, '2025-03-12 16:29:52', '');
-INSERT INTO `mx_sim` VALUES (164, 4, '0003', '2', '', 'A4', NULL, NULL, NULL, NULL, NULL, '2025-03-12 16:29:53', '');
-INSERT INTO `mx_sim` VALUES (165, 5, '0003', '2', '', 'A5', NULL, NULL, NULL, NULL, NULL, '2025-03-12 16:29:53', '');
-INSERT INTO `mx_sim` VALUES (166, 6, '0003', '2', '', 'A6', NULL, NULL, NULL, NULL, NULL, '2025-03-12 16:29:53', '');
-INSERT INTO `mx_sim` VALUES (167, 7, '0003', '2', '', 'A7', NULL, NULL, NULL, NULL, NULL, '2025-03-12 16:29:23', '');
-INSERT INTO `mx_sim` VALUES (168, 8, '0003', '2', '', 'A8', NULL, NULL, NULL, NULL, NULL, '2025-03-12 16:29:53', '');
-INSERT INTO `mx_sim` VALUES (169, 9, '0003', '2', '', 'A9', NULL, NULL, NULL, NULL, NULL, '2025-03-12 16:29:53', '');
-INSERT INTO `mx_sim` VALUES (170, 10, '0003', '2', '', 'AA', NULL, NULL, NULL, NULL, NULL, '2025-03-12 16:29:53', '');
+INSERT INTO `mx_sim` VALUES (1, 1, '0001', '0', '030000A2', '01', '2025-03-19 16:41:33', '2025-03-19 16:41:33', NULL, NULL, NULL, '2025-03-19 16:41:33', '');
+INSERT INTO `mx_sim` VALUES (2, 2, '0001', '0', '030000A2', '02', '2025-03-19 17:07:28', '2025-03-19 17:07:28', NULL, NULL, NULL, '2025-03-19 17:07:28', '');
+INSERT INTO `mx_sim` VALUES (3, 3, '0001', '0', '030000A2', '03', '2025-03-19 18:38:29', '2025-03-19 18:38:29', NULL, NULL, NULL, '2025-03-19 18:38:29', '');
+INSERT INTO `mx_sim` VALUES (4, 4, '0001', '0', '030000A2', '04', '2025-03-19 18:16:30', '2025-03-19 18:16:30', NULL, NULL, NULL, '2025-03-19 20:18:40', '');
+INSERT INTO `mx_sim` VALUES (5, 5, '0001', '0', '030000A2', '05', '2025-03-19 16:44:31', '2025-03-19 16:44:31', NULL, NULL, NULL, '2025-03-19 16:44:31', '');
+INSERT INTO `mx_sim` VALUES (6, 6, '0001', '0', '030000A2', '06', '2025-03-19 18:45:50', '2025-03-19 18:45:50', NULL, NULL, NULL, '2025-03-19 18:45:50', '');
+INSERT INTO `mx_sim` VALUES (7, 7, '0001', '0', '030000A2', '07', '2025-03-19 17:51:05', '2025-03-19 17:51:05', NULL, NULL, NULL, '2025-03-21 15:18:36', '');
+INSERT INTO `mx_sim` VALUES (8, 8, '0001', '0', '030000A2', '08', '2025-03-19 18:00:15', '2025-03-19 18:00:15', NULL, NULL, NULL, '2025-03-19 19:40:11', '');
+INSERT INTO `mx_sim` VALUES (9, 9, '0001', '0', '030000A2', '09', '2025-03-19 15:39:10', '2025-03-19 15:39:10', NULL, NULL, NULL, '2025-03-19 17:25:24', '');
+INSERT INTO `mx_sim` VALUES (10, 10, '0001', '0', '030000A2', '0A', '2025-03-12 21:01:30', NULL, NULL, NULL, NULL, '2025-03-15 12:40:55', '');
+INSERT INTO `mx_sim` VALUES (81, 1, '0002', '0', '030000A2', '51', '2025-03-18 18:47:35', '2025-03-18 18:47:35', NULL, NULL, NULL, '2025-03-18 18:47:35', '');
+INSERT INTO `mx_sim` VALUES (82, 2, '0002', '0', '030000A2', '52', '2025-03-18 18:28:33', '2025-03-18 18:28:33', NULL, NULL, NULL, '2025-03-18 18:28:33', '');
+INSERT INTO `mx_sim` VALUES (83, 3, '0002', '0', '030000A2', '53', '2025-03-18 17:17:02', '2025-03-18 17:17:02', NULL, NULL, NULL, '2025-03-18 17:17:02', '');
+INSERT INTO `mx_sim` VALUES (84, 4, '0002', '0', '030000A2', '54', '2025-03-18 19:34:09', '2025-03-18 19:34:09', NULL, NULL, NULL, '2025-03-18 19:34:09', '');
+INSERT INTO `mx_sim` VALUES (85, 5, '0002', '0', '030000A2', '55', '2025-03-18 18:08:27', '2025-03-18 18:08:27', NULL, NULL, NULL, '2025-03-18 18:08:27', '');
+INSERT INTO `mx_sim` VALUES (86, 6, '0002', '0', '030000A2', '56', '2025-03-18 20:06:45', '2025-03-18 20:06:45', NULL, NULL, NULL, '2025-03-18 20:06:45', '');
+INSERT INTO `mx_sim` VALUES (87, 7, '0002', '0', '030000A2', '57', '2025-03-18 19:54:36', '2025-03-18 19:54:36', NULL, NULL, NULL, '2025-03-18 19:54:36', '');
+INSERT INTO `mx_sim` VALUES (88, 8, '0002', '0', '030000A2', '58', '2025-03-18 19:05:04', '2025-03-18 19:05:04', NULL, NULL, NULL, '2025-03-18 19:05:04', '');
+INSERT INTO `mx_sim` VALUES (89, 9, '0002', '0', '030000A2', '59', '2025-03-18 16:59:12', '2025-03-18 16:59:12', NULL, NULL, NULL, '2025-03-18 16:59:12', '');
+INSERT INTO `mx_sim` VALUES (90, 10, '0002', '0', '030000A2', '5A', '2025-03-18 17:49:22', '2025-03-18 17:49:22', NULL, NULL, NULL, '2025-03-18 17:49:22', '');
+INSERT INTO `mx_sim` VALUES (161, 1, '0003', '0', '030000A2', 'A1', '2025-03-17 14:21:19', '2025-03-17 14:21:19', NULL, NULL, NULL, '2025-03-17 14:21:19', '');
+INSERT INTO `mx_sim` VALUES (162, 2, '0003', '0', '030000A2', 'A2', '2025-03-17 13:37:25', '2025-03-17 13:37:25', NULL, NULL, NULL, '2025-03-17 13:37:25', '');
+INSERT INTO `mx_sim` VALUES (163, 3, '0003', '0', '030000A2', 'A3', '2025-03-17 13:46:22', '2025-03-17 13:46:22', NULL, NULL, NULL, '2025-03-17 13:46:22', '');
+INSERT INTO `mx_sim` VALUES (164, 4, '0003', '0', '030000A2', 'A4', '2025-03-17 15:12:12', '2025-03-17 13:49:12', NULL, NULL, NULL, '2025-03-17 15:12:12', '');
+INSERT INTO `mx_sim` VALUES (165, 5, '0003', '0', '030000A2', 'A5', '2025-03-17 14:04:58', '2025-03-17 14:04:58', NULL, NULL, NULL, '2025-03-17 14:38:15', '');
+INSERT INTO `mx_sim` VALUES (166, 6, '0003', '0', '030000A2', 'A6', '2025-03-17 13:52:11', '2025-03-17 13:52:11', NULL, NULL, NULL, '2025-03-17 14:21:15', '');
+INSERT INTO `mx_sim` VALUES (167, 7, '0003', '0', '030000A2', 'A7', '2025-03-17 15:08:33', '2025-03-17 15:08:33', NULL, NULL, NULL, '2025-03-17 15:08:33', '');
+INSERT INTO `mx_sim` VALUES (168, 8, '0003', '0', '030000A2', 'A8', '2025-03-17 15:48:59', '2025-03-17 15:32:36', NULL, NULL, NULL, '2025-03-17 15:48:59', '');
+INSERT INTO `mx_sim` VALUES (169, 9, '0003', '0', '030000A2', 'A9', '2025-03-12 21:01:24', NULL, NULL, NULL, NULL, '2025-03-15 12:41:52', '');
+INSERT INTO `mx_sim` VALUES (170, 10, '0003', '0', '030000A2', 'AA', '2025-03-17 14:42:29', '2025-03-17 14:42:29', NULL, NULL, NULL, '2025-03-17 15:13:10', '');
 
 SET FOREIGN_KEY_CHECKS = 1;

+ 8 - 8
pla-sim/01_SQL/02_table/sim_seat.sql

@@ -1,17 +1,17 @@
 /*
  Navicat Premium Dump SQL
 
- Source Server         : 47.104.188.84-sim
+ Source Server         : fhxy-192.168.1.61-polardbx
  Source Server Type    : MySQL
- Source Server Version : 80020 (8.0.20)
- Source Host           : 47.104.188.84:65006
- Source Schema         : pla-chem-sim-dev-1
+ Source Server Version : 80032 (8.0.32-X-Cluster-8.4.19-20241112)
+ Source Host           : 192.168.1.61:4886
+ Source Schema         : pla-chem-sim-dev-2
 
  Target Server Type    : MySQL
- Target Server Version : 80020 (8.0.20)
+ Target Server Version : 80032 (8.0.32-X-Cluster-8.4.19-20241112)
  File Encoding         : 65001
 
- Date: 12/03/2025 16:29:56
+ Date: 21/03/2025 15:46:45
 */
 
 SET NAMES utf8mb4;
@@ -26,8 +26,8 @@ CREATE TABLE `sim_seat`  (
   `seat_num` int NOT NULL DEFAULT 0 COMMENT '座号',
   `seat_bind_ip` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '[电脑]绑定的[IP地址]',
   `seat_rs485_ip` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '[RS485]绑定的[IP地址]',
-  `seat_rs485_port` int NOT NULL COMMENT '[RS485]绑定的[端口]',
-  `seat_rs485_socket_state` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'Socket状态:[0]:初始化,[1]:打开,[2]:关闭,[5]:禁用',
+  `seat_rs485_port` int NOT NULL DEFAULT 0 COMMENT '[RS485]绑定的[端口]',
+  `seat_rs485_socket_state` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT 'Socket状态:[0]:初始化,[1]:打开,[2]:关闭,[5]:禁用',
   `current_user_id` bigint NOT NULL DEFAULT 0 COMMENT '当前座上学员/用户ID',
   `current_sim_id` bigint NOT NULL DEFAULT 0 COMMENT '模拟器的ID:[0]没有连接任何模拟器,[xx]:具体某台模拟器',
   `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '创建者',

+ 7 - 7
pla-sim/01_SQL/02_table/sim_sim.sql

@@ -1,17 +1,17 @@
 /*
  Navicat Premium Dump SQL
 
- Source Server         : 47.104.188.84-sim
+ Source Server         : fhxy-192.168.1.61-polardbx
  Source Server Type    : MySQL
- Source Server Version : 80020 (8.0.20)
- Source Host           : 47.104.188.84:65006
- Source Schema         : pla-chem-sim-dev-1
+ Source Server Version : 80032 (8.0.32-X-Cluster-8.4.19-20241112)
+ Source Host           : 192.168.1.61:4886
+ Source Schema         : pla-chem-sim-dev-2
 
  Target Server Type    : MySQL
- Target Server Version : 80020 (8.0.20)
+ Target Server Version : 80032 (8.0.32-X-Cluster-8.4.19-20241112)
  File Encoding         : 65001
 
- Date: 12/03/2025 16:29:47
+ Date: 21/03/2025 15:46:51
 */
 
 SET NAMES utf8mb4;
@@ -50,7 +50,7 @@ INSERT INTO `sim_sim` VALUES (6, 6, '0001', '0', '', '06', NULL, NULL, NULL, NUL
 INSERT INTO `sim_sim` VALUES (7, 7, '0001', '0', '', '07', NULL, NULL, NULL, NULL, NULL, NULL, '');
 INSERT INTO `sim_sim` VALUES (8, 8, '0001', '0', '', '08', NULL, NULL, NULL, NULL, NULL, NULL, '');
 INSERT INTO `sim_sim` VALUES (9, 9, '0001', '0', '', '09', NULL, NULL, NULL, NULL, NULL, NULL, '');
-INSERT INTO `sim_sim` VALUES (10, 10, '0001', '0', '', '10', NULL, NULL, NULL, NULL, NULL, NULL, '');
+INSERT INTO `sim_sim` VALUES (10, 10, '0001', '0', '', '0A', NULL, NULL, NULL, NULL, NULL, NULL, '');
 INSERT INTO `sim_sim` VALUES (81, 1, '0002', '0', '', '51', NULL, NULL, NULL, NULL, NULL, NULL, '');
 INSERT INTO `sim_sim` VALUES (82, 2, '0002', '0', '', '52', NULL, NULL, NULL, NULL, NULL, NULL, '');
 INSERT INTO `sim_sim` VALUES (83, 3, '0002', '0', '', '53', NULL, NULL, NULL, NULL, NULL, NULL, '');

Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 1676
pla-sim/01_SQL/03_dev_backup/pla-chem-sim-dev-1.sql


Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 4898
pla-sim/01_SQL/04_dev_backup_47-104-188-84/pla-chem-sim-dev-1.sql


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

+ 52 - 0
ruoyi-sim/src/main/java/com/ruoyi/sim/domain/vo/SeatVo.java

@@ -0,0 +1,52 @@
+package com.ruoyi.sim.domain.vo;
+
+import com.ruoyi.sim.domain.Seat;
+
+public class SeatVo extends Seat {
+
+    private Long simId = 0L;
+    private String simState = "";
+    private String simType = "";
+    private String simSn = "";
+    private String simNum = "";
+
+    public Long getSimId() {
+        return simId;
+    }
+
+    public void setSimId(Long simId) {
+        this.simId = simId;
+    }
+
+    public String getSimState() {
+        return simState;
+    }
+
+    public void setSimState(String simState) {
+        this.simState = simState;
+    }
+
+    public String getSimType() {
+        return simType;
+    }
+
+    public void setSimType(String simType) {
+        this.simType = simType;
+    }
+
+    public String getSimSn() {
+        return simSn;
+    }
+
+    public void setSimSn(String simSn) {
+        this.simSn = simSn;
+    }
+
+    public String getSimNum() {
+        return simNum;
+    }
+
+    public void setSimNum(String simNum) {
+        this.simNum = simNum;
+    }
+}

+ 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();
-    }
-}

+ 4 - 0
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommBuildService.java

@@ -12,6 +12,10 @@ import org.springframework.stereotype.Service;
 
 import static com.ruoyi.sim.constant.CommConst.*;
 
+/**
+ * 万能询问报文
+ * AA000103B100000000E0BE55
+ */
 @Service
 public class CommBuildService {
 

+ 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]: ''

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.