|  | @@ -98,8 +98,39 @@ public class CommSendService {
 | 
	
		
			
				|  |  |          readAll();
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 开始考试以后,交卷之前,定时任务中间读取值,作为答题值。有优先级高的任务可能跳过执行。
 | 
	
		
			
				|  |  | +     *
 | 
	
		
			
				|  |  | +     * @param re
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    public void readOneExamAtMiddle(RealExam re) {
 | 
	
		
			
				|  |  | +        l.info("readOneExamAtMiddle getExamId = {}", re.getExamId());
 | 
	
		
			
				|  |  | +        List<RealExamFault> list = realExamFaultService.listAllType2State2and3ByExamId(re.getExamId());
 | 
	
		
			
				|  |  | +        for (RealExamFault ref : list) {
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                RealExamFault refQ = realExamFaultService.selectRealExamFaultByRefId(ref.getRefId());
 | 
	
		
			
				|  |  | +                if (refQ == null || refQ.getExamId() == 0L) {
 | 
	
		
			
				|  |  | +                    continue;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                if (!RealExamFault.State.WRITTEN.equals(ref.getRefState()) &&
 | 
	
		
			
				|  |  | +                        !RealExamFault.State.LOOP_READ.equals(ref.getRefState())) {
 | 
	
		
			
				|  |  | +                    continue;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            Seat seat = seatService.selectSeatBySeatId(re.getSeatId());
 | 
	
		
			
				|  |  | +            Sim sim = simService.selectSimBySimId(re.getSimId());
 | 
	
		
			
				|  |  | +            Fault f = faultService.selectFaultByFaultId(ref.getFaultId());
 | 
	
		
			
				|  |  | +            readOneSimOneFaultResistance(seat, sim, ref, f, RealExamFault.State.LOOP_READ);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 交卷最后读取值,作为答题值。
 | 
	
		
			
				|  |  | +     *
 | 
	
		
			
				|  |  | +     * @param re
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  |      public void readOneExamAtLast(RealExam re) {
 | 
	
		
			
				|  |  | -        l.info("readOneExamAtLast");
 | 
	
		
			
				|  |  | +        l.info("readOneExamAtLast getExamId = {}", re.getExamId());
 | 
	
		
			
				|  |  |          List<RealExamFault> list = realExamFaultService.listAllType2State2and3ByExamId(re.getExamId());
 | 
	
		
			
				|  |  |          for (RealExamFault ref : list) {
 | 
	
		
			
				|  |  |              Seat seat = seatService.selectSeatBySeatId(re.getSeatId());
 | 
	
	
		
			
				|  | @@ -823,7 +854,7 @@ public class CommSendService {
 | 
	
		
			
				|  |  |       * @param sim
 | 
	
		
			
				|  |  |       * @param reF
 | 
	
		
			
				|  |  |       * @param f
 | 
	
		
			
				|  |  | -     * @param refState 中间轮询是null,交卷最后一次读取为finish状态。用来修改状态的。debug模式下执行为null。
 | 
	
		
			
				|  |  | +     * @param refState 修改的目标状态。debug模式下执行为null。
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  |      public void readOneSimOneFaultResistance(Seat seat, Sim sim, RealExamFault reF, Fault f, String refState) {
 | 
	
		
			
				|  |  |          l.info("readOneSimOneFaultResistance");
 | 
	
	
		
			
				|  | @@ -831,16 +862,26 @@ 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, commStrategy.getSleepShort());
 | 
	
		
			
				|  |  | +                sm2 = send(sm1, seat, sim,
 | 
	
		
			
				|  |  | +                        RETRY_COUNT_READ_ONE_RESISTANCE_FINAL, commStrategy.getSleepShort());
 | 
	
		
			
				|  |  | +            } else if (RealExamFault.State.LOOP_READ.equals(refState)) { // 是否是中间读取
 | 
	
		
			
				|  |  | +                sm2 = send(sm1, seat, sim,
 | 
	
		
			
				|  |  | +                        RETRY_COUNT_READ_ONE_RESISTANCE_MIDDLE, commStrategy.getSleepShort(), false);
 | 
	
		
			
				|  |  |              } else {
 | 
	
		
			
				|  |  | -                sm2 = send(sm1, seat, sim, RETRY_COUNT_0, commStrategy.getSleepShort());
 | 
	
		
			
				|  |  | +                sm2 = send(sm1, seat, sim,
 | 
	
		
			
				|  |  | +                        RETRY_COUNT_0, commStrategy.getSleepShort());
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          } else {
 | 
	
		
			
				|  |  | -            sm2 = send(sm1, seat, sim, RETRY_COUNT_READ_ONE_RESISTANCE, commStrategy.getSleepShort());
 | 
	
		
			
				|  |  | +            sm2 = send(sm1, seat, sim, RETRY_COUNT_READ_ONE_RESISTANCE_FINAL, commStrategy.getSleepShort());
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          simReceiveService.setFaultAnswerValue(sm2, sim, reF, f, refState);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    public SimMsg send(final SimMsg sm, final Seat seat, final Sim sim,
 | 
	
		
			
				|  |  | +                       final int retryTotalCount, final long sleep) {
 | 
	
		
			
				|  |  | +        return send(sm, seat, sim, retryTotalCount, sleep, true);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  |       * 最基本的通信方法。
 | 
	
		
			
				|  |  |       * send hex message
 | 
	
	
		
			
				|  | @@ -852,51 +893,66 @@ public class CommSendService {
 | 
	
		
			
				|  |  |       * @param sim             可以为空!更新最后发送/接收时间 用。
 | 
	
		
			
				|  |  |       * @param retryTotalCount 重试次数
 | 
	
		
			
				|  |  |       * @param sleep           不使用传入0,不进行挂起。
 | 
	
		
			
				|  |  | +     * @param importantTask
 | 
	
		
			
				|  |  |       * @return
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  | -    public 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, final boolean importantTask) {
 | 
	
		
			
				|  |  | +        if (!config.isCommGlobal()) {
 | 
	
		
			
				|  |  | +            l.warn("isCommGlobal == false [模拟器通信被禁用!]");
 | 
	
		
			
				|  |  | +            return sm;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if (sm == null || sm.getSendMsg() == null || StringUtils.isBlank(sm.getSendMsg())) {
 | 
	
		
			
				|  |  | +            throw new IllegalArgumentException("SimMsg IllegalArgument");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        // sim
 | 
	
		
			
				|  |  | +        if (seat == null) {
 | 
	
		
			
				|  |  | +            throw new IllegalArgumentException("seat is null");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if (sleep < 0) {
 | 
	
		
			
				|  |  | +            throw new IllegalArgumentException("SimMsg sleep");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        // log.
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            l.info("####发送#### == Seat[{}],SimMsg[{}]", seat, sm);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        SimSocketParamVo sspv = seat.toSimSocketParamVo();
 | 
	
		
			
				|  |  |          try {
 | 
	
		
			
				|  |  | -            if (!config.isCommGlobal()) {
 | 
	
		
			
				|  |  | -                l.warn("isCommGlobal == false [模拟器通信被禁用!]");
 | 
	
		
			
				|  |  | -                return sm;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            if (sm == null || sm.getSendMsg() == null || StringUtils.isBlank(sm.getSendMsg())) {
 | 
	
		
			
				|  |  | -                throw new IllegalArgumentException("SimMsg IllegalArgument");
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            // sim
 | 
	
		
			
				|  |  | -            if (seat == null) {
 | 
	
		
			
				|  |  | -                throw new IllegalArgumentException("seat is null");
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            if (sleep < 0) {
 | 
	
		
			
				|  |  | -                throw new IllegalArgumentException("SimMsg sleep");
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            // log.
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                l.info("####发送#### == Seat[{}],SimMsg[{}]", seat, sm);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  |              // 如果没有打开socket,顺道打开。正好后面要sleep。
 | 
	
		
			
				|  |  |              // 不强制重开Socket。
 | 
	
		
			
				|  |  |              // 先进行Socket相关处理。
 | 
	
		
			
				|  |  | -            SimSocketParamVo sspv = seat.toSimSocketParamVo();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 优先级高的在运行,跳过
 | 
	
		
			
				|  |  | +            if (importantTask == false && socketService.getImportantTaskRunning(sspv)) {
 | 
	
		
			
				|  |  | +                sm.setResult(SimMsg.Result.SKIP);
 | 
	
		
			
				|  |  | +                socketService.setImportantTaskRunning(sspv, false);
 | 
	
		
			
				|  |  | +                l.warn("####跳过运行#### sm = {}", sm);
 | 
	
		
			
				|  |  | +                return sm;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            if (importantTask) {
 | 
	
		
			
				|  |  | +                socketService.setImportantTaskRunning(sspv, true);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |              socketService.openOne(sspv);
 | 
	
		
			
				|  |  |              // Socket情况不正确,直接返回。
 | 
	
		
			
				|  |  |              if (socketService.isNotOk(sspv)) {
 | 
	
		
			
				|  |  |                  sm.setResult(SimMsg.Result.SOCKET_CONNECT_EXCEPTION);
 | 
	
		
			
				|  |  | +                socketService.setImportantTaskRunning(sspv, false);
 | 
	
		
			
				|  |  |                  return sm;
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  |                  // sleep挂起线程,追求顺序请求。
 | 
	
		
			
				|  |  |                  // 大于0才挂起。
 | 
	
		
			
				|  |  | -                if (sleep > 0 && socketService.get(sspv).getPreviousSendSleep() > 0L) {
 | 
	
		
			
				|  |  | +                if (sleep > 0 && socketService.getVo(sspv).getPreviousSendSleep() > 0L) {
 | 
	
		
			
				|  |  |                      // 时间间隔挂起。
 | 
	
		
			
				|  |  | -                    Thread.sleep(socketService.get(sspv).getPreviousSendSleep());
 | 
	
		
			
				|  |  | +                    Thread.sleep(socketService.getVo(sspv).getPreviousSendSleep());
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | -            socketService.get(sspv).setPreviousSendSleep(sleep);
 | 
	
		
			
				|  |  | -            Socket socket = socketService.get(sspv).getSocket();
 | 
	
		
			
				|  |  | +            socketService.getVo(sspv).setPreviousSendSleep(sleep);
 | 
	
		
			
				|  |  | +            Socket socket = socketService.getVo(sspv).getSocket();
 | 
	
		
			
				|  |  |              InputStream is = socket.getInputStream();
 | 
	
		
			
				|  |  |              OutputStream os = socket.getOutputStream();
 | 
	
		
			
				|  |  | -            socket.setSoTimeout(commStrategy.getSoTimeout());
 | 
	
		
			
				|  |  | +            Sim simSeat = simService.selectSimBySimId(seat.getCurrentSimId());
 | 
	
		
			
				|  |  | +            socket.setSoTimeout(commStrategy.getSoTimeout(simSeat));
 | 
	
		
			
				|  |  |              os.write(hexStrToByteArrs(sm.getSendMsg()));
 | 
	
		
			
				|  |  |              sm.setSendTime(DateUtils.getNowDate());
 | 
	
		
			
				|  |  |              if (sim != null) {
 | 
	
	
		
			
				|  | @@ -920,6 +976,7 @@ public class CommSendService {
 | 
	
		
			
				|  |  |                      // todo:
 | 
	
		
			
				|  |  |                      l.warn("####接收错误@格式错误#### = sm = {},ar = {}", sm, ar);
 | 
	
		
			
				|  |  |                      sm.setResult(SimMsg.Result.RECEIVE_CHECK_FAIL);
 | 
	
		
			
				|  |  | +                    socketService.setImportantTaskRunning(sspv, false);
 | 
	
		
			
				|  |  |                      return sm;
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |              }
 | 
	
	
		
			
				|  | @@ -928,6 +985,7 @@ public class CommSendService {
 | 
	
		
			
				|  |  |                  if (ar.isError()) {
 | 
	
		
			
				|  |  |                      l.warn("####接收错误@匹配错误#### sm = {},ar = {}", sm, ar);
 | 
	
		
			
				|  |  |                      sm.setResult(SimMsg.Result.RECEIVE_NOT_MATCH);
 | 
	
		
			
				|  |  | +                    socketService.setImportantTaskRunning(sspv, false);
 | 
	
		
			
				|  |  |                      return sm;
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |              }
 | 
	
	
		
			
				|  | @@ -936,6 +994,7 @@ public class CommSendService {
 | 
	
		
			
				|  |  |                  simService.updateLastReceivedTime(sim);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |              sm.setResult(SimMsg.Result.SUCCESS);
 | 
	
		
			
				|  |  | +            socketService.setImportantTaskRunning(sspv, false);
 | 
	
		
			
				|  |  |              // 最后返回报文实体。
 | 
	
		
			
				|  |  |              return sm;
 | 
	
		
			
				|  |  |          } catch (InterruptedException | IOException e) {
 | 
	
	
		
			
				|  | @@ -943,10 +1002,10 @@ public class CommSendService {
 | 
	
		
			
				|  |  |              l.error("SocketTimeoutException");
 | 
	
		
			
				|  |  |              e.printStackTrace();
 | 
	
		
			
				|  |  |              sm.setResult(SimMsg.Result.READ_TIMEOUT_EXCEPTION);
 | 
	
		
			
				|  |  | +            socketService.setImportantTaskRunning(sspv, false);
 | 
	
		
			
				|  |  |              if (sim != null) {
 | 
	
		
			
				|  |  |                  l.info("fail sim.getSimId() = {}", sim.getSimId());
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | -            SimSocketParamVo sspv = seat.toSimSocketParamVo();
 | 
	
		
			
				|  |  |              // Socket失败计数
 | 
	
		
			
				|  |  |              socketService.failedPlus1(sspv);
 | 
	
		
			
				|  |  |              if (socketService.failedIsReachedMax(sspv, SocketService.SOCKET_CONNECT_RETRY_COUNT_LIMIT)) {
 |