CommCheckService.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  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
  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.tryOpenAll();
  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 smS01 = commBuildService.buildSendMsgWhichSim();
  126. SimMsg smR01 = commSendService.send(smS01, seat, null, retryTotalCount, commStrategy.getSleepShort());
  127. Integer result = smR01.getResult();
  128. if (Objects.equals(result, SimMsg.Result.SUCCESS)) {
  129. final String simNum = CommParseUtils.subSimNum(smR01);
  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.updateSimIdBySeatNum(seat.getSeatNum(), sim.getSimId());
  138. // 更新Sim状态
  139. simService.updateSimStateBySimId(sim.getSimId(), Sim.State.ONLINE);
  140. String msgTemp = "座号[{0}]-模拟器[{1}]型[{2}]在线";
  141. String msg = MessageFormat.format(msgTemp, seat.getSeatNum(), Sim.TYPE_NAME_MAP.get(sim.getSimType()), sim.getSimNum());
  142. return AjaxResult.success(msg);
  143. } else if (Objects.equals(result, SimMsg.Result.RECEIVE_CHECK_FAIL)) {
  144. return AjaxResult.error("失败,报文回复异常。");
  145. } else if (Objects.equals(result, SimMsg.Result.SOCKET_CONNECT_EXCEPTION)) {
  146. // 更新SimId
  147. seatService.updateSimIdBySeatNum(seat.getSeatNum(), Sim.ID_0);
  148. String msgTemp = "座号[{0}]-没有连接任何接模拟器,检查线缆连接和线缆开关";
  149. String msg = MessageFormat.format(msgTemp, seat.getSeatNum());
  150. return AjaxResult.success(msg);
  151. }
  152. return AjaxResult.error("失败");
  153. }
  154. /**
  155. * 纯数据库查询,模拟器是否在线。
  156. * 模拟器是否被禁用。
  157. *
  158. * @param simId
  159. * @return
  160. */
  161. public AjaxResult checkOneSimOnlineState(final Long simId) {
  162. if (simId == null || simId <= 0) {
  163. return AjaxResult.error("没有连接任何接模拟器,<br>检查线缆连接和线缆开关!");
  164. }
  165. Sim sim = simService.selectSimBySimId(simId);
  166. if (sim != null) {
  167. switch (sim.getSimState()) {
  168. case Sim.State.ONLINE: {
  169. return AjaxResult.success("模拟器[" + sim.getSimNum() + "]在线!");
  170. }
  171. case Sim.State.OFFLINE: {
  172. return AjaxResult.success("模拟器[" + sim.getSimNum() + "]离线!");
  173. }
  174. case Sim.State.DISABLE: {
  175. return AjaxResult.error("模拟器[" + sim.getSimNum() + "]禁用!");
  176. }
  177. }
  178. }
  179. return AjaxResult.error("模拟器[" + Objects.requireNonNull(sim).getSimNum() + "]XXXX!");
  180. }
  181. /**
  182. * 默认Seat中已经有CurrentSimId数据
  183. * 检查回应报文模拟器类型是否正确。
  184. *
  185. * @param seat 座次
  186. * @param important
  187. * @param targetSimType 期望模拟器目标类型
  188. * @return
  189. */
  190. public AjaxResult checkOneSimType(final Seat seat, final boolean important, final String targetSimType) {
  191. // check args.
  192. if (seat == null) {
  193. throw new IllegalArgumentException("seat is null");
  194. }
  195. if (seat.getCurrentSimId() == null || Sim.ID_0.equals(seat.getCurrentSimId())) {
  196. throw new IllegalArgumentException("sim id is 0");
  197. }
  198. if (!simService.existBySimId(seat.getCurrentSimId())) {
  199. return AjaxResult.error("模拟器ID[" + seat.getCurrentSimId() + "]不存在!");
  200. }
  201. //
  202. final String msgErrorTemp = "连接模拟器类型或序列号不正确!<br>应该连接模拟器型号:<br>";
  203. final String msgOk = "连接模拟器类型或序列号正确!";
  204. int retryTotalCount;
  205. if (important) {
  206. retryTotalCount = RETRY_COUNT_QUERY_SN_IMPORTANT;
  207. } else {
  208. retryTotalCount = RETRY_COUNT_0;
  209. }
  210. Sim sim = simService.selectSimBySimId(seat.getCurrentSimId());
  211. SimMsg smS = commBuildService.buildSendMsgReadSimType(sim.getSimNum());
  212. SimMsg smR = commSendService.send(smS, seat, sim, retryTotalCount, commStrategy.getSleepShort());
  213. if (StringUtils.isNotBlank(smR.getReceiveMsg())) {
  214. final String content = CommParseUtils.subContentData(smR);
  215. switch (targetSimType) {
  216. case Sim.TYPE_0001 -> {
  217. if (content.startsWith(CommConst.TYPE_0001_SN_PREFIX) && content.endsWith(sim.getSimNum())) {
  218. return AjaxResult.success(msgOk);
  219. } else {
  220. return AjaxResult.error(msgErrorTemp + Sim.TYPE_NAME_MAP.get(targetSimType));
  221. }
  222. }
  223. case Sim.TYPE_0002 -> {
  224. if (content.startsWith(CommConst.TYPE_0002_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_0003 -> {
  231. if (content.startsWith(CommConst.TYPE_0003_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. default -> throw new IllegalStateException("Unexpected value: " + targetSimType);
  238. }
  239. }
  240. return AjaxResult.error("失败,检查一个模拟器[" + sim.getSimNum() + "]型号或序列号执行错误!");
  241. }
  242. /**
  243. * 默认Seat中已经有CurrentSimId数据
  244. *
  245. * @param seat
  246. * @param important
  247. * @return
  248. */
  249. @Transactional
  250. public AjaxResult checkOneSimOnlineState(final Seat seat, final boolean important) {
  251. // check args.
  252. if (seat == null) {
  253. throw new IllegalArgumentException("seat is null");
  254. }
  255. if (seat.getCurrentSimId() == null || Sim.ID_0.equals(seat.getCurrentSimId())) {
  256. return AjaxResult.error("模拟器ID不存在!");
  257. }
  258. if (!simService.existBySimId(seat.getCurrentSimId())) {
  259. return AjaxResult.error("模拟器ID[" + seat.getCurrentSimId() + "]不存在!");
  260. }
  261. //
  262. int retryTotalCount;
  263. if (important) {
  264. retryTotalCount = RETRY_COUNT_QUERY_SN_IMPORTANT;
  265. } else {
  266. retryTotalCount = RETRY_COUNT_0;
  267. }
  268. Sim sim = simService.selectSimBySimId(seat.getCurrentSimId());
  269. SimMsg smS02 = commBuildService.buildSendMsgReadSimType(sim.getSimNum());
  270. SimMsg smR02 = commSendService.send(smS02, seat, sim, retryTotalCount, commStrategy.getSleepShort());
  271. if (StringUtils.isNotBlank(smR02.getReceiveMsg())) {
  272. // 只要返回正确报文,即认为在线。
  273. simService.updateSimStateBySimId(sim.getSimId(), Sim.State.ONLINE);
  274. socketService.failedReset0(seat.toSimSocketParamVo());
  275. return AjaxResult.success("成功,检查一个模拟器[" + sim.getSimNum() + "]OK!");
  276. }
  277. return AjaxResult.error("失败,检查一个模拟器[" + sim.getSimNum() + "]在线状态执行错误!");
  278. }
  279. /**
  280. * [定时执行]查找所有没有被手动禁用的座次 和 座次上的模拟器。
  281. */
  282. public AjaxResult checkAllSeatAndSimState() {
  283. List<Seat> list = seatService.listAllEnable();
  284. list.forEach(seat -> {
  285. checkOneSeatState(seat, false);
  286. // checkOneSimState(seat, false);
  287. });
  288. return AjaxResult.success("检查完毕,成功!");
  289. }
  290. }