|  | @@ -15,10 +15,13 @@ import com.xunmei.host.websocket.redis.delay.RedisDelayQueueHandle;
 | 
	
		
			
				|  |  |  import com.xunmei.host.websocket.redis.delay.RedisDelayedQueueUtil;
 | 
	
		
			
				|  |  |  import com.xunmei.host.websocket.service.WebsocketService;
 | 
	
		
			
				|  |  |  import com.xunmei.system.api.util.LogUtils;
 | 
	
		
			
				|  |  | +import lombok.SneakyThrows;
 | 
	
		
			
				|  |  |  import org.springframework.scheduling.annotation.Async;
 | 
	
		
			
				|  |  |  import org.springframework.stereotype.Service;
 | 
	
		
			
				|  |  |  import org.springframework.transaction.annotation.Propagation;
 | 
	
		
			
				|  |  |  import org.springframework.transaction.annotation.Transactional;
 | 
	
		
			
				|  |  | +import org.springframework.transaction.support.TransactionSynchronizationAdapter;
 | 
	
		
			
				|  |  | +import org.springframework.transaction.support.TransactionSynchronizationManager;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import javax.annotation.Resource;
 | 
	
		
			
				|  |  |  import java.time.LocalDateTime;
 | 
	
	
		
			
				|  | @@ -41,7 +44,7 @@ public class IotWebsocketMsgServiceImpl extends ServiceImpl<IotWebsocketMsgMappe
 | 
	
		
			
				|  |  |      @Async(ThreadPoolConfig.HOST_EXECUTOR)
 | 
	
		
			
				|  |  |      @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
 | 
	
		
			
				|  |  |      public void saveMsg(WebsocketExecuteReq req, String receiveMsg) {
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +        //刚刚收到消息,还没开始处理业务逻辑,先保存消息数据
 | 
	
		
			
				|  |  |          final IotServerInfo serverInfo = req.getServerInfo();
 | 
	
		
			
				|  |  |          final IotWebsocketMsg msg = new IotWebsocketMsg();
 | 
	
		
			
				|  |  |          msg.setId(req.getId());
 | 
	
	
		
			
				|  | @@ -54,7 +57,7 @@ public class IotWebsocketMsgServiceImpl extends ServiceImpl<IotWebsocketMsgMappe
 | 
	
		
			
				|  |  |          msg.setReceiveContent(receiveMsg);
 | 
	
		
			
				|  |  |          msg.setMaxRetryTimes(3);
 | 
	
		
			
				|  |  |          msg.setCurRetryTimes(0);
 | 
	
		
			
				|  |  | -        msg.setRetryInterval(3);
 | 
	
		
			
				|  |  | +        msg.setRetryInterval(1);
 | 
	
		
			
				|  |  |          msg.setCreateTime(LocalDateTime.now());
 | 
	
		
			
				|  |  |          msg.setUpdateTime(LocalDateTime.now());
 | 
	
		
			
				|  |  |          save(msg);
 | 
	
	
		
			
				|  | @@ -65,12 +68,13 @@ public class IotWebsocketMsgServiceImpl extends ServiceImpl<IotWebsocketMsgMappe
 | 
	
		
			
				|  |  |      @Async(ThreadPoolConfig.HOST_EXECUTOR)
 | 
	
		
			
				|  |  |      @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
 | 
	
		
			
				|  |  |      public void sendSuccessMsg(String msgId) {
 | 
	
		
			
				|  |  | +        //业务处理完成,回复成功了
 | 
	
		
			
				|  |  |          final IotWebsocketMsg websocketMsg = getById(msgId);
 | 
	
		
			
				|  |  |          if (websocketMsg == null) {
 | 
	
		
			
				|  |  |              return;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          websocketMsg.setStatus(MessageStatusEnum.SUCCESS.getCode());
 | 
	
		
			
				|  |  | -        if (websocketMsg.getReadySendTime()==null){
 | 
	
		
			
				|  |  | +        if (websocketMsg.getReadySendTime() == null) {
 | 
	
		
			
				|  |  |              websocketMsg.setReadySendTime(LocalDateTime.now());
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          websocketMsg.setReallySendTime(LocalDateTime.now());
 | 
	
	
		
			
				|  | @@ -83,13 +87,16 @@ public class IotWebsocketMsgServiceImpl extends ServiceImpl<IotWebsocketMsgMappe
 | 
	
		
			
				|  |  |      @Async(ThreadPoolConfig.HOST_EXECUTOR)
 | 
	
		
			
				|  |  |      @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
 | 
	
		
			
				|  |  |      public void sendSuccessMsg(WebsocketResult res, String msgId) {
 | 
	
		
			
				|  |  | +        //业务处理完成,回复成功了
 | 
	
		
			
				|  |  |          final IotWebsocketMsg websocketMsg = getById(msgId);
 | 
	
		
			
				|  |  |          if (websocketMsg == null) {
 | 
	
		
			
				|  |  |              return;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          websocketMsg.setStatus(MessageStatusEnum.SUCCESS.getCode());
 | 
	
		
			
				|  |  |          websocketMsg.setReplyContent(JacksonUtils.toJSONString(res));
 | 
	
		
			
				|  |  | -        websocketMsg.setReadySendTime(LocalDateTime.now());
 | 
	
		
			
				|  |  | +        if (websocketMsg.getReadySendTime()==null){
 | 
	
		
			
				|  |  | +            websocketMsg.setReadySendTime(LocalDateTime.now());
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |          websocketMsg.setReallySendTime(LocalDateTime.now());
 | 
	
		
			
				|  |  |          websocketMsg.setUpdateTime(LocalDateTime.now());
 | 
	
		
			
				|  |  |          updateById(websocketMsg);
 | 
	
	
		
			
				|  | @@ -100,22 +107,29 @@ public class IotWebsocketMsgServiceImpl extends ServiceImpl<IotWebsocketMsgMappe
 | 
	
		
			
				|  |  |      @Async(ThreadPoolConfig.HOST_EXECUTOR)
 | 
	
		
			
				|  |  |      @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
 | 
	
		
			
				|  |  |      public void sendFailMsg(WebsocketResult res, String msgId) {
 | 
	
		
			
				|  |  | -        //收到消息处理完成后第一次发送,但是发送失败了
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          final IotWebsocketMsg websocketMsg = getById(msgId);
 | 
	
		
			
				|  |  |          if (websocketMsg == null) {
 | 
	
		
			
				|  |  |              return;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          final LocalDateTime now = LocalDateTime.now();
 | 
	
		
			
				|  |  | -        websocketMsg.setReplyContent(JacksonUtils.toJSONString(res));
 | 
	
		
			
				|  |  | -        websocketMsg.setStatus(MessageStatusEnum.RETRYING.getCode());
 | 
	
		
			
				|  |  | -        websocketMsg.setReadySendTime(now);
 | 
	
		
			
				|  |  | +        //final LocalDateTime firTime = websocketMsg.getFireTime() == null ? now : websocketMsg.getFireTime();
 | 
	
		
			
				|  |  | +        final Integer curRetryTimes = websocketMsg.getCurRetryTimes();
 | 
	
		
			
				|  |  | +        if (curRetryTimes == 0) {
 | 
	
		
			
				|  |  | +            //收到消息处理完成后第一次发送,但是发送失败了
 | 
	
		
			
				|  |  | +            websocketMsg.setReadySendTime(now);
 | 
	
		
			
				|  |  | +            websocketMsg.setReplyContent(JacksonUtils.toJSONString(res));
 | 
	
		
			
				|  |  | +            websocketMsg.setStatus(MessageStatusEnum.RETRYING.getCode());
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |          websocketMsg.setFireTime(now.plusMinutes(websocketMsg.getRetryInterval()));
 | 
	
		
			
				|  |  | +        //websocketMsg.setFireTime((firTime).plusSeconds(60));
 | 
	
		
			
				|  |  |          websocketMsg.setUpdateTime(now);
 | 
	
		
			
				|  |  |          updateById(websocketMsg);
 | 
	
		
			
				|  |  |          RedisDelayedQueueUtil.addDelayQueue(msgId, websocketMsg.getFireTime(), RedisDelayQueueEnum.WEBSOCKET_MSG_RETRY.getCode());
 | 
	
		
			
				|  |  |          LogUtils.WS_MSG_RETRY_LOG.info("主机消息回复失败,已添加延迟队列,等待重试,消息内容: {}", JacksonUtils.toJSONString(websocketMsg));
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    @SneakyThrows
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
 | 
	
		
			
				|  |  |      public void execute(Object o) {
 | 
	
	
		
			
				|  | @@ -127,14 +141,22 @@ public class IotWebsocketMsgServiceImpl extends ServiceImpl<IotWebsocketMsgMappe
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          final Integer maxRetryTimes = msg.getMaxRetryTimes();
 | 
	
		
			
				|  |  |          final Integer curRetryTimes = msg.getCurRetryTimes();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          if (curRetryTimes < maxRetryTimes) {
 | 
	
		
			
				|  |  | -            websocketService.sendMsgByTokens(msg, msg.getIotCode());
 | 
	
		
			
				|  |  | +            //第一次重试, 把消息放到队列中
 | 
	
		
			
				|  |  |              msg.setCurRetryTimes(curRetryTimes + 1);
 | 
	
		
			
				|  |  |              updateById(msg);
 | 
	
		
			
				|  |  | -            LogUtils.WS_MSG_RETRY_LOG.error("开始第{}次重试Ws消息,msgId: {}", msg.getCurRetryTimes(), msgId);
 | 
	
		
			
				|  |  | -            return;
 | 
	
		
			
				|  |  | +            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
 | 
	
		
			
				|  |  | +                @Override
 | 
	
		
			
				|  |  | +                public void afterCommit() {
 | 
	
		
			
				|  |  | +                    websocketService.sendMsgByTokens(msg, msg.getIotCode());
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            });
 | 
	
		
			
				|  |  | +            LogUtils.WS_MSG_RETRY_LOG.info("开始第{}次重试Ws消息,msgId: {}", msg.getCurRetryTimes(), msgId);
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +            msg.setStatus(MessageStatusEnum.RETRY_FAIL.getCode());
 | 
	
		
			
				|  |  | +            updateById(msg);
 | 
	
		
			
				|  |  | +            LogUtils.WS_MSG_RETRY_LOG.info("重试次数已达到最大值,停止重试,msgId: {}", msgId);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 |