CommCheckService.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. package com.ruoyi.sim.service.impl;
  2. import com.ruoyi.common.core.domain.AjaxResult;
  3. import com.ruoyi.sim.constant.CommConst;
  4. import com.ruoyi.sim.domain.Seat;
  5. import com.ruoyi.sim.domain.Sim;
  6. import com.ruoyi.sim.domain.SimMsg;
  7. import org.apache.commons.lang3.StringUtils;
  8. import org.slf4j.Logger;
  9. import org.slf4j.LoggerFactory;
  10. import org.springframework.beans.factory.annotation.Autowired;
  11. import org.springframework.stereotype.Service;
  12. import org.springframework.transaction.annotation.Transactional;
  13. import java.io.IOException;
  14. import java.net.InetAddress;
  15. import java.net.UnknownHostException;
  16. import java.text.MessageFormat;
  17. import java.util.List;
  18. import java.util.Objects;
  19. import static com.ruoyi.sim.constant.CommConst.RETRY_COUNT_0;
  20. import static com.ruoyi.sim.constant.CommConst.RETRY_COUNT_QUERY_SN_IMPORTANT;
  21. @Service
  22. public class CommCheckService {
  23. private static final Logger l = LoggerFactory.getLogger(CommCheckService.class);
  24. @Autowired
  25. private SeatService seatService;
  26. @Autowired
  27. private SimService simService;
  28. @Autowired
  29. private CommBuildService commBuildService;
  30. @Autowired
  31. private CommSendService commSendService;
  32. @Autowired
  33. private SocketService socketService;
  34. @Autowired
  35. private CommStrategy commStrategy;
  36. /**
  37. * 等同于ping命令。
  38. *
  39. * @param ipV4
  40. * @return
  41. * @throws IOException
  42. */
  43. public boolean pingIsReachable(String ipV4) {
  44. InetAddress ia = null;
  45. try {
  46. ia = InetAddress.getByName(ipV4);
  47. return ia.isReachable(CommConst.PING_TIME_OUT);
  48. } catch (UnknownHostException e) {
  49. e.printStackTrace();
  50. return false;
  51. } catch (IOException e) {
  52. e.printStackTrace();
  53. return false;
  54. }
  55. }
  56. /**
  57. * ping路由器得到状态
  58. *
  59. * @param routerIp
  60. * @return
  61. */
  62. public AjaxResult checkRouterState(final String routerIp) {
  63. if (routerIp == null || StringUtils.isBlank(routerIp)) {
  64. throw new IllegalArgumentException("routerIp isBlank");
  65. }
  66. if (pingIsReachable(routerIp)) {
  67. return AjaxResult.success();
  68. } else {
  69. simService.updateAllEnableState(Sim.State.OFFLINE);
  70. seatService.updateAllEnableState(Seat.SocketState.OFFLINE);
  71. return AjaxResult.error("路由器[" + routerIp + "]无法连接!");
  72. }
  73. }
  74. /**
  75. * pingRS485得到状态
  76. *
  77. * @param rs485Ip
  78. * @return
  79. */
  80. public AjaxResult checkPingRs485State(final String rs485Ip) {
  81. if (rs485Ip == null || StringUtils.isBlank(rs485Ip)) {
  82. throw new IllegalArgumentException("rs485Ip isBlank");
  83. }
  84. if (pingIsReachable(rs485Ip)) {
  85. return AjaxResult.success();
  86. } else {
  87. // 更新SocketState
  88. seatService.updateSocketStateByRs485Ip(rs485Ip, Seat.SocketState.OFFLINE);
  89. return AjaxResult.error("RS485物联网网关[" + rs485Ip + "]无法连接!");
  90. }
  91. }
  92. public AjaxResult checkPingStudentPcState(final String studentIp) {
  93. if (studentIp == null || StringUtils.isBlank(studentIp)) {
  94. throw new IllegalArgumentException("studentIp isBlank");
  95. }
  96. if (pingIsReachable(studentIp)) {
  97. return AjaxResult.success();
  98. } else {
  99. return AjaxResult.error("学员操作端[" + studentIp + "]无法连接!");
  100. }
  101. }
  102. /**
  103. * 检查一个座次状况。
  104. * 维护 seat表-socket_state字段;
  105. * 维护 seat表-sim_id字段;
  106. * 维护 sim表-Online、Offline状态;
  107. *
  108. * @param seat 座次
  109. * @param important true:重要的场景 开始考试 重试次数不同,也会进行序列号检查。false:不重要场景 定时巡查。
  110. * @return 在线的话,带一个Sim对象出来。离线Sim对象为空。
  111. */
  112. public AjaxResult checkOneSeatState(final Seat seat, final boolean important) {
  113. // check args.
  114. if (seat == null) {
  115. throw new IllegalArgumentException("seat is null");
  116. }
  117. //
  118. socketService.tryOpenOne(seat.toSimSocketParamVo());
  119. int retryTotalCount;
  120. if (important) {
  121. retryTotalCount = CommConst.RETRY_COUNT_WHICH_SIM_IMPORTANT;
  122. } else {
  123. retryTotalCount = CommConst.RETRY_COUNT_0;
  124. }
  125. SimMsg smS = commBuildService.buildSendMsgWhichSim();
  126. SimMsg smR = commSendService.send(smS, seat, null, retryTotalCount, commStrategy.getSleepShort());
  127. Integer result = smR.getResult();
  128. if (Objects.equals(result, SimMsg.Result.SUCCESS)) {
  129. final String simNum = CommParseUtils.subSimNum(smR.getReceiveMsg());
  130. Sim sim = simService.uniqueBySimNum(simNum);
  131. if (sim == null) {
  132. return AjaxResult.error("找不到模拟器[" + simNum + "]对应数据。");
  133. } else {
  134. l.info("座号[{}]上发现模拟器[{}]", seat.getSeatNum(), sim.getSimNum());
  135. }
  136. // 更新SimId
  137. seatService.updateCurrentSimIdBySeatNum(seat.getSeatNum(), sim.getSimId());
  138. // 更新Sim状态
  139. simService.updateSimStateBySimId(sim.getSimId(), Sim.State.ONLINE);
  140. // 查询出最新的Sim对象
  141. sim = simService.uniqueBySimNum(simNum);
  142. //
  143. String msgTemp = "座号[{0}]-模拟器[{1}]型[{2}]在线";
  144. String msg = MessageFormat.format(msgTemp, seat.getSeatNum(), Sim.TYPE_NAME_MAP.get(sim.getSimType()), sim.getSimNum());
  145. // 成功的话,Obj为Sim对象。
  146. return AjaxResult.success(msg, sim);
  147. } else if (Objects.equals(result, SimMsg.Result.RECEIVE_CHECK_FAIL)) {
  148. return smR.getDefaultErrorAR();
  149. } else if (Objects.equals(result, SimMsg.Result.READ_TIMEOUT_EXCEPTION)) {
  150. // 更新SimId
  151. seatService.updateCurrentSimIdBySeatNum(seat.getSeatNum(), Sim.ID_0);
  152. String msgTemp = "座号[{0}]-没有连接任何接模拟器,检查线缆连接和线缆开关";
  153. String msg = MessageFormat.format(msgTemp, seat.getSeatNum());
  154. // 失败的话,Obj为空。
  155. return AjaxResult.success(msg, null);
  156. } else if (Objects.equals(result, SimMsg.Result.RECEIVE_NOT_MATCH)) {
  157. return smR.getDefaultErrorAR();
  158. }
  159. return AjaxResult.error("检查座次模拟器失败!", null);
  160. }
  161. /**
  162. * 纯数据库查询,模拟器是否在线。
  163. * 模拟器是否被禁用。
  164. *
  165. * @param simId
  166. * @return
  167. */
  168. public AjaxResult checkOneSimOnlineState(final Long simId) {
  169. if (simId == null || simId <= 0) {
  170. return AjaxResult.error("没有连接任何接模拟器,<br>检查线缆连接和线缆开关!");
  171. }
  172. Sim sim = simService.selectSimBySimId(simId);
  173. if (sim != null) {
  174. switch (sim.getSimState()) {
  175. case Sim.State.ONLINE: {
  176. return AjaxResult.success("模拟器[" + sim.getSimNum() + "]在线!");
  177. }
  178. case Sim.State.OFFLINE: {
  179. return AjaxResult.success("模拟器[" + sim.getSimNum() + "]离线!");
  180. }
  181. case Sim.State.DISABLE: {
  182. return AjaxResult.error("模拟器[" + sim.getSimNum() + "]禁用!");
  183. }
  184. }
  185. }
  186. return AjaxResult.error("模拟器[" + Objects.requireNonNull(sim).getSimNum() + "]XXXX!");
  187. }
  188. /**
  189. * 默认Seat中已经有CurrentSimId数据
  190. * 检查回应报文模拟器类型是否正确。
  191. *
  192. * @param seat 座次
  193. * @param important
  194. * @param targetSimType 期望模拟器目标类型
  195. * @return
  196. */
  197. public AjaxResult checkOneSimType(final Seat seat, final boolean important, final String targetSimType) {
  198. // check args.
  199. if (seat == null) {
  200. throw new IllegalArgumentException("seat is null");
  201. }
  202. if (seat.getCurrentSimId() == null || Sim.ID_0.equals(seat.getCurrentSimId())) {
  203. throw new IllegalArgumentException("sim id is 0");
  204. }
  205. if (!simService.existBySimId(seat.getCurrentSimId())) {
  206. return AjaxResult.error("模拟器ID[" + seat.getCurrentSimId() + "]不存在!");
  207. }
  208. //
  209. final String msgErrorTemp = "连接模拟器类型或序列号不正确!<br>应该连接模拟器型号:<br>";
  210. final String msgOk = "连接模拟器类型或序列号正确!";
  211. int retryTotalCount;
  212. if (important) {
  213. retryTotalCount = RETRY_COUNT_QUERY_SN_IMPORTANT;
  214. } else {
  215. retryTotalCount = RETRY_COUNT_0;
  216. }
  217. Sim sim = simService.selectSimBySimId(seat.getCurrentSimId());
  218. SimMsg smS = commBuildService.buildSendMsgReadSimType(sim.getSimNum());
  219. SimMsg smR = commSendService.send(smS, seat, sim, retryTotalCount, commStrategy.getSleepShort());
  220. if (StringUtils.isNotBlank(smR.getReceiveMsg())) {
  221. final String content = CommParseUtils.subContentData(smR);
  222. switch (targetSimType) {
  223. case Sim.TYPE_0001 -> {
  224. if (content.startsWith(CommConst.TYPE_0001_SN_PREFIX) && content.endsWith(sim.getSimNum())) {
  225. return AjaxResult.success(msgOk);
  226. } else {
  227. return AjaxResult.error(msgErrorTemp + Sim.TYPE_NAME_MAP.get(targetSimType));
  228. }
  229. }
  230. case Sim.TYPE_0002 -> {
  231. if (content.startsWith(CommConst.TYPE_0002_SN_PREFIX) && content.endsWith(sim.getSimNum())) {
  232. return AjaxResult.success(msgOk);
  233. } else {
  234. return AjaxResult.error(msgErrorTemp + Sim.TYPE_NAME_MAP.get(targetSimType));
  235. }
  236. }
  237. case Sim.TYPE_0003 -> {
  238. if (content.startsWith(CommConst.TYPE_0003_SN_PREFIX) && content.endsWith(sim.getSimNum())) {
  239. return AjaxResult.success(msgOk);
  240. } else {
  241. return AjaxResult.error(msgErrorTemp + Sim.TYPE_NAME_MAP.get(targetSimType));
  242. }
  243. }
  244. default -> throw new IllegalStateException("Unexpected value: " + targetSimType);
  245. }
  246. }
  247. return AjaxResult.error("失败,检查一个模拟器[" + sim.getSimNum() + "]型号或序列号执行错误!<br/>请检查模拟器线缆连接情况和连接模拟器型号!");
  248. }
  249. /**
  250. * 默认Seat中已经有CurrentSimId数据
  251. *
  252. * @param seat
  253. * @param important
  254. * @return
  255. */
  256. @Transactional
  257. public AjaxResult checkOneSimOnlineState(final Seat seat, final boolean important) {
  258. // check args.
  259. if (seat == null) {
  260. throw new IllegalArgumentException("seat is null");
  261. }
  262. if (seat.getCurrentSimId() == null || Sim.ID_0.equals(seat.getCurrentSimId())) {
  263. return AjaxResult.error("模拟器ID不存在!");
  264. }
  265. if (!simService.existBySimId(seat.getCurrentSimId())) {
  266. return AjaxResult.error("模拟器ID[" + seat.getCurrentSimId() + "]不存在!");
  267. }
  268. //
  269. int retryTotalCount;
  270. if (important) {
  271. retryTotalCount = RETRY_COUNT_QUERY_SN_IMPORTANT;
  272. } else {
  273. retryTotalCount = RETRY_COUNT_0;
  274. }
  275. Sim sim = simService.selectSimBySimId(seat.getCurrentSimId());
  276. SimMsg smS02 = commBuildService.buildSendMsgReadSimType(sim.getSimNum());
  277. SimMsg smR02 = commSendService.send(smS02, seat, sim, retryTotalCount, commStrategy.getSleepShort());
  278. if (StringUtils.isNotBlank(smR02.getReceiveMsg())) {
  279. // 只要返回正确报文,即认为在线。
  280. simService.updateSimStateBySimId(sim.getSimId(), Sim.State.ONLINE);
  281. socketService.failedReset0(seat.toSimSocketParamVo());
  282. return AjaxResult.success("成功,检查一个模拟器[" + sim.getSimNum() + "]OK!");
  283. }
  284. return AjaxResult.error("失败,检查一个模拟器[" + sim.getSimNum() + "]在线状态执行错误!");
  285. }
  286. /**
  287. * [定时执行]查找所有没有被手动禁用的座次 和 座次上的模拟器。
  288. */
  289. public AjaxResult checkAllSeatAndSimState() {
  290. List<Seat> list = seatService.listAllEnable();
  291. list.forEach(seat -> {
  292. checkOneSeatState(seat, false);
  293. // checkOneSimState(seat, false);
  294. });
  295. return AjaxResult.success("检查完毕,成功!");
  296. }
  297. }