package com.ard.work.config; import com.ard.work.domain.enums.RouteEvent; import com.ard.work.domain.enums.RouteState; import lombok.RequiredArgsConstructor; import org.springframework.messaging.Message; import org.springframework.messaging.support.MessageBuilder; import org.springframework.statemachine.StateMachine; import org.springframework.statemachine.service.StateMachineService; import org.springframework.statemachine.support.DefaultExtendedState; import org.springframework.statemachine.support.DefaultStateMachineContext; import org.springframework.stereotype.Service; import java.util.concurrent.ConcurrentHashMap; @Service @RequiredArgsConstructor public class RouteStateMachineService { private final StateMachineService stateMachineService; private final RouteStateMachineListener listener; private final ConcurrentHashMap listenerRegisteredMap = new ConcurrentHashMap<>(); private StateMachine getStateMachine(String boxSn) { StateMachine stateMachine = stateMachineService.acquireStateMachine(boxSn); // 使用原子操作确保 listener 只添加一次 listenerRegisteredMap.computeIfAbsent(boxSn, k -> { stateMachine.addStateListener(listener); return true; }); stateMachine.start(); return stateMachine; } /** * 发送事件到指定boxSn的状态机 */ public boolean sendEvent(String boxSn, RouteEvent event) { try { // 获取/创建指定boxSn的状态机实例 StateMachine stateMachine = getStateMachine(boxSn); // 构建事件消息(携带boxSn作为头信息) Message message = MessageBuilder .withPayload(event) .setHeader("boxSn", boxSn) .build(); // 发送事件并返回执行结果 return stateMachine.sendEvent(message); } catch (Exception e) { // 异常处理:日志记录、状态机重置等 throw new RuntimeException("发送航线状态事件失败,boxSn=" + boxSn + ", event=" + event, e); } } /** * 获取指定boxSn的当前状态 */ public RouteState getCurrentState(String boxSn) { try { StateMachine stateMachine = stateMachineService.acquireStateMachine(boxSn); return stateMachine.getState().getId(); } catch (Exception e) { // 未找到状态机实例时返回初始状态 return RouteState.IDLE; } } /** * 释放指定boxSn的状态机实例(可选,节省资源) */ public void releaseStateMachine(String boxSn) { stateMachineService.releaseStateMachine(boxSn); } /** * 重置指定boxSn的状态机(恢复到初始状态) */ public void resetStateMachine(String boxSn) { try { StateMachine stateMachine = stateMachineService.acquireStateMachine(boxSn); // 1️⃣ 停止状态机 stateMachine.stop(); // 2️⃣ 构造 ExtendedState(可选,但强烈推荐) DefaultExtendedState extendedState = new DefaultExtendedState(); extendedState.getVariables().put("boxSn", boxSn); // 3️⃣ 重置状态机到 IDLE stateMachine.getStateMachineAccessor() .doWithAllRegions(accessor -> { accessor.resetStateMachine( new DefaultStateMachineContext<>( RouteState.IDLE, // 初始状态 null, // event null, // event headers extendedState // 扩展状态 ) ); }); // 4️⃣ 重新启动 stateMachine.start(); } catch (Exception e) { throw new RuntimeException("重置航线状态机失败,boxSn=" + boxSn, e); } } }