diff --git a/src/main/java/club/joylink/rtss/controller/simulation/rt/RtSimulationController.java b/src/main/java/club/joylink/rtss/controller/simulation/rt/RtSimulationController.java index 1c421c63f..bb1a3acfe 100644 --- a/src/main/java/club/joylink/rtss/controller/simulation/rt/RtSimulationController.java +++ b/src/main/java/club/joylink/rtss/controller/simulation/rt/RtSimulationController.java @@ -4,10 +4,12 @@ import club.joylink.rtss.constants.MapPrdTypeEnum; import club.joylink.rtss.simulation.cbtc.data.vo.SimulationVO; import club.joylink.rtss.simulation.rt.RtSimulationService; import club.joylink.rtss.vo.LoginUserInfoVO; +import club.joylink.rtss.vo.UserVO; import club.joylink.rtss.vo.client.map.MapVO; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; @RestController @RequestMapping("/rtSimulation") @@ -33,4 +35,16 @@ public class RtSimulationController { return rtSimulationService.getMapData(id); } + @ApiOperation(value = "退出计划") + @PostMapping("/{id}/planOver") + public void planOver(@PathVariable String id) { + this.rtSimulationService.init(id); + } + + @ApiOperation(value = "清除仿真") + @DeleteMapping("/{group}/clear") + public void clearSimulation(@PathVariable String group, @ApiIgnore @RequestAttribute UserVO user) { + this.rtSimulationService.clearSimulation(group, user); + } + } diff --git a/src/main/java/club/joylink/rtss/simulation/Simulation.java b/src/main/java/club/joylink/rtss/simulation/Simulation.java index 364e87d81..e9aaeaba7 100644 --- a/src/main/java/club/joylink/rtss/simulation/Simulation.java +++ b/src/main/java/club/joylink/rtss/simulation/Simulation.java @@ -370,6 +370,10 @@ public abstract class Simulation getSimulationMembers() { + return new ArrayList<>(this.simulationMemberMap.values()); + } + public List querySimulationMembersOfRole(Object role) { return this.simulationMemberMap.values().stream() .filter(m -> Objects.equals(m.getRole(), role)) diff --git a/src/main/java/club/joylink/rtss/simulation/SimulationCommonController.java b/src/main/java/club/joylink/rtss/simulation/SimulationCommonController.java index 0d8dd4f24..571764b56 100644 --- a/src/main/java/club/joylink/rtss/simulation/SimulationCommonController.java +++ b/src/main/java/club/joylink/rtss/simulation/SimulationCommonController.java @@ -43,6 +43,11 @@ public class SimulationCommonController { this.simulationManager.updateSpeed(id, speed); } + @GetMapping("/{id}/members") + public List getSimulationMembers(@PathVariable String id) { + return this.simulationManager.getSimulationMembers(id); + } + @PostMapping("/{id}/member/{memberId}/operate/{type}") public Object operate(@PathVariable String id, @PathVariable String memberId, @PathVariable String type, @RequestBody Map params) { @@ -54,6 +59,11 @@ public class SimulationCommonController { this.simulationManager.memberPlayedByUser(id, memberId, userId); } + @GetMapping("/{id}/users") + public List getSimulationUsers(@PathVariable String id) { + return this.simulationManager.getSimulationUsers(id); + } + @DeleteMapping("/{id}/destroy") public void destroy(@PathVariable String id) { this.simulationManager.destroy(id); diff --git a/src/main/java/club/joylink/rtss/simulation/SimulationManager.java b/src/main/java/club/joylink/rtss/simulation/SimulationManager.java index 8e6d3b657..3c4dae0fd 100644 --- a/src/main/java/club/joylink/rtss/simulation/SimulationManager.java +++ b/src/main/java/club/joylink/rtss/simulation/SimulationManager.java @@ -3,6 +3,7 @@ package club.joylink.rtss.simulation; import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import club.joylink.rtss.simulation.event.SimulationMemberPlayChangeEvent; import club.joylink.rtss.simulation.messaging.websocket.DefaultMessageSender; +import club.joylink.rtss.simulation.rt.RtSimulation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; @@ -144,4 +145,14 @@ public class SimulationManager { public List getSimulationList() { return new ArrayList<>(simulationCache.values()); } + + public List getSimulationMembers(String id) { + Simulation simulation = getById(id); + return simulation.getSimulationMembers(); + } + + public List getSimulationUsers(String id) { + Simulation simulation = getById(id); + return simulation.getSimulationUsers(); + } } diff --git a/src/main/java/club/joylink/rtss/simulation/SimulationUser.java b/src/main/java/club/joylink/rtss/simulation/SimulationUser.java index 56d63f77d..6dbccb4d1 100644 --- a/src/main/java/club/joylink/rtss/simulation/SimulationUser.java +++ b/src/main/java/club/joylink/rtss/simulation/SimulationUser.java @@ -44,14 +44,14 @@ public abstract class SimulationUser { BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED .assertNotTrue(set.contains(destination)); set.add(destination); - log.debug(String.format("用户[%s]订阅[%s-%s]", wsSessionId, destination)); + log.debug(String.format("用户[%s]订阅[%s-%s]", this.id, wsSessionId, destination)); } public void unsubscribe(String wsSessionId, String destination) { Set set = wsSubscribeMap.get(wsSessionId); if (set != null) { set.remove(destination); - log.debug(String.format("用户[%s]取消了订阅[%s-%s]", wsSessionId, destination)); + log.debug(String.format("用户[%s]取消了订阅[%s-%s]", this.id, wsSessionId, destination)); } } @@ -66,7 +66,7 @@ public abstract class SimulationUser { public void disconnect(String wsSessionId) { this.wsSubscribeMap.remove(wsSessionId); - log.debug(String.format("用户[%s]断开了连接[%s]", wsSessionId)); + log.debug(String.format("用户[%s]断开了连接[%s]", this.id, wsSessionId)); } public void play(SimulationMember member) { diff --git a/src/main/java/club/joylink/rtss/simulation/rt/ATS/AtsApiService.java b/src/main/java/club/joylink/rtss/simulation/rt/ATS/AtsApiService.java index f05496992..4f92663e4 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/ATS/AtsApiService.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/ATS/AtsApiService.java @@ -16,7 +16,7 @@ public class AtsApiService { AtsSwitch atsSwitch = atsRepository.getSwitchById(cilSwitch.getId()); if (atsSwitch.getPosition() != cilSwitch.getPosition()) { atsSwitch.setPosition(cilSwitch.getPosition()); - atsRepository.ready2Send(atsSwitch.getId()); + atsRepository.ready2Send(atsSwitch.getId(), 1, atsSwitch.getPosition()); } } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/ATS/AtsLogicService.java b/src/main/java/club/joylink/rtss/simulation/rt/ATS/AtsLogicService.java index 0946f9aa1..bd9fa57fa 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/ATS/AtsLogicService.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/ATS/AtsLogicService.java @@ -1,13 +1,16 @@ package club.joylink.rtss.simulation.rt.ATS; +import club.joylink.rtss.simulation.SimulationUser; import club.joylink.rtss.simulation.rt.ATS.bo.AtsRepository; import club.joylink.rtss.simulation.rt.ATS.bo.AtsRepositoryBuilder; -import club.joylink.rtss.simulation.rt.CIL.bo.CilDevice; import club.joylink.rtss.simulation.rt.RtSimulation; +import club.joylink.rtss.simulation.rt.RtSimulationSubscribeTopic; import club.joylink.rtss.vo.client.map.MapVO; -import club.joylink.rtss.vo.client.map.newmap.MapGraphDataNewVO; -import club.joylink.rtss.vo.client.map.newmap.MapLogicDataNewVO; import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import java.util.ArrayList; +import java.util.List; /** * ATS逻辑 @@ -18,4 +21,29 @@ public class AtsLogicService { AtsRepository atsRepository = AtsRepositoryBuilder.buildFrom(mapVO); rtSimulation.addRepository(atsRepository); } + + public void addJobs(RtSimulation rtSimulation) { + for (RtSimulationSubscribeTopic topic : RtSimulationSubscribeTopic.values()) { + rtSimulation.addJob("MESSAGE-" + topic.name(), () -> sendMessages(rtSimulation, topic), topic.getRate()); + } + } + + public void sendMessages(RtSimulation rtSimulation, RtSimulationSubscribeTopic topic) { + AtsRepository repository = rtSimulation.getRepository(AtsRepository.NAME, AtsRepository.class); + List> messages = repository.removeReady2SendMessages(); + if (!CollectionUtils.isEmpty(messages)) { + List simulationUsers = rtSimulation.getSimulationUsers(); + String dest = topic.buildDestination(rtSimulation.getId()); + for (SimulationUser simulationUser : simulationUsers) { + if (simulationUser.isSubscribe(dest)) { + rtSimulation.pushMessageToUser(simulationUser.getId(), dest, messages); + } + } + } + } + + public List> getAllMessages(RtSimulation rtSimulation) { + AtsRepository repository = rtSimulation.getRepository(AtsRepository.NAME, AtsRepository.class); + return repository.getAllMessages(); + } } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsRepository.java b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsRepository.java index 48f05ad47..c2f473606 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsRepository.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsRepository.java @@ -4,6 +4,7 @@ import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import club.joylink.rtss.simulation.SimulationRepository; import club.joylink.rtss.simulation.cbtc.data.map.Station; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -15,7 +16,7 @@ public class AtsRepository extends SimulationRepository { // TODO: 2021/4/22 如果设备id有重复,那不同类的设备的消息需要分开存 Map> messageMap = new HashMap<>(); - Map> sendMessageMap = new HashMap<>(); + Map> ready2SendMessageMap = new HashMap<>(); Map routeMap = new HashMap<>(); Map runPlanMap = new HashMap<>(); @@ -48,7 +49,22 @@ public class AtsRepository extends SimulationRepository { return atsSwitch; } - public void ready2Send(String id) { - sendMessageMap.putIfAbsent(id, messageMap.get(id)); + public void ready2Send(String id, int i, Object value) { + List message = messageMap.get(id); + if (message != null) { + message.set(i, value); + ready2SendMessageMap.putIfAbsent(id, message); + } + } + + public List> removeReady2SendMessages() { + ArrayList> messages = new ArrayList<>(this.ready2SendMessageMap.values()); + ready2SendMessageMap.clear(); + return messages; + + } + + public List> getAllMessages() { + return new ArrayList<>(this.messageMap.values()); } } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsRepositoryBuilder.java b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsRepositoryBuilder.java index 5d152c28a..9e56f7736 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsRepositoryBuilder.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsRepositoryBuilder.java @@ -26,7 +26,7 @@ public class AtsRepositoryBuilder { for (MapSwitchVO switchVO : switchList) { AtsSwitch atsSwitch = new AtsSwitch(switchVO.getCode(), switchVO.getName()); switchMap.put(atsSwitch.getId(), atsSwitch); - + messageMap.put(atsSwitch.getId(), atsSwitch.buildMessage()); } } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsSwitch.java b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsSwitch.java index caab76762..4d4d6cae3 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsSwitch.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsSwitch.java @@ -1,8 +1,11 @@ package club.joylink.rtss.simulation.rt.ATS.bo; +import club.joylink.rtss.simulation.rt.RtSimulationSubscribeTopic; import lombok.Getter; +import lombok.NonNull; import lombok.Setter; +import java.util.Arrays; import java.util.List; @Getter @@ -13,4 +16,8 @@ public class AtsSwitch extends AtsDevice { super(id, name); } + public List buildMessage() { + return Arrays.asList(id, position); + } + } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilLogicService.java b/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilLogicService.java index ec74fb74a..fb156f170 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilLogicService.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilLogicService.java @@ -1,5 +1,6 @@ package club.joylink.rtss.simulation.rt.CIL; +import club.joylink.rtss.simulation.rt.ATS.AtsApiService; import club.joylink.rtss.simulation.rt.CIL.bo.*; import club.joylink.rtss.simulation.rt.RtSimulation; import club.joylink.rtss.simulation.rt.SRD.SrdApiService; @@ -27,6 +28,9 @@ public class CilLogicService { @Autowired private CilRouteLogicService cilRouteLogicService; + @Autowired + private AtsApiService atsApiService; + public void buildRepository(RtSimulation rtSimulation, MapVO mapVO) { CilRepository cilRepository = CilRepositoryBuilder.buildFrom(mapVO); rtSimulation.addRepository(cilRepository); @@ -40,6 +44,9 @@ public class CilLogicService { rtSimulation.addJob("cilMainLogic", () -> this.mainLogic(rtSimulation, cilRepository), CilMainLogicRate); + rtSimulation.addJob("cilStateSend2Ats", + () -> sendState2Ats(rtSimulation, cilRepository), + DeviceStateCollectRate); } private void collectDeviceState(RtSimulation rtSimulation, CilRepository repository) { @@ -72,4 +79,10 @@ public class CilLogicService { private void mainLogic(RtSimulation rtSimulation, CilRepository cilRepository) { this.cilRouteLogicService.routeLogic(rtSimulation, cilRepository); } + + private void sendState2Ats(RtSimulation rtSimulation, CilRepository cilRepository) { + for (CilSwitch cilSwitch : cilRepository.getSwitches()) { + atsApiService.handle(rtSimulation, cilSwitch); + } + } } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilRepository.java b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilRepository.java index dd3583bef..f81cc5542 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilRepository.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilRepository.java @@ -67,6 +67,10 @@ public class CilRepository extends SimulationRepository { return cilSwitch; } + public List getSwitches() { + return new ArrayList<>(switchMap.values()); + } + public CilSignal getSignalById(String id) { CilSignal cilSignal = this.signalMap.get(id); BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(cilSignal); diff --git a/src/main/java/club/joylink/rtss/simulation/rt/RtSimulationService.java b/src/main/java/club/joylink/rtss/simulation/rt/RtSimulationService.java index 476d5f66e..16396104c 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/RtSimulationService.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/RtSimulationService.java @@ -32,6 +32,8 @@ public class RtSimulationService { private SrdLogicService srdLogicService; @Autowired private AtsLogicService atsLogicService; + @Autowired + private RtSimulationSubscribeMessageService rtSimulationSubscribeMessageService; public RtSimulation create(UserVO userVO, Long mapId, MapPrdTypeEnum prdTypeEnum) { Objects.requireNonNull(mapId); @@ -43,16 +45,17 @@ public class RtSimulationService { this.simulationManager.save(rtSimulation); this.srdLogicService.addJobs(rtSimulation); this.cilLogicService.addJobs(rtSimulation); + this.atsLogicService.addJobs(rtSimulation); this.initSimulationMember(rtSimulation); this.initCreatorPlayMember(rtSimulation); + rtSimulation.addSubscribeMessageService(rtSimulationSubscribeMessageService); + simulationManager.start(rtSimulation.getId()); return rtSimulation; } private void initCreatorPlayMember(RtSimulation rtSimulation) { - if (MapPrdTypeEnum.LOCAL.equals(rtSimulation.getPrdType())) { - List memberList = rtSimulation.querySimulationMembersOfRole(RtSimulationMember.Role.LOWS); - this.simulationManager.memberPlayedByUser(rtSimulation.getId(), memberList.get(0).getId(), rtSimulation.getCreator().getId()); - } + List memberList = rtSimulation.querySimulationMembersOfRole(RtSimulationMember.Role.LOWS); + this.simulationManager.memberPlayedByUser(rtSimulation.getId(), memberList.get(0).getId(), rtSimulation.getCreator().getId()); } private void initSimulationMember(RtSimulation rtSimulation) { @@ -86,4 +89,13 @@ public class RtSimulationService { RtSimulation rtSimulation = simulationManager.getById(id, RtSimulation.class); return rtSimulation.getMapVO(); } + + public void init(String id) { + RtSimulation rtSimulation = simulationManager.getById(id, RtSimulation.class); + rtSimulation.init(); + } + + public void clearSimulation(String group, UserVO user) { + + } } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/RtSimulationSubscribeMessageService.java b/src/main/java/club/joylink/rtss/simulation/rt/RtSimulationSubscribeMessageService.java index 3e9f4071a..52ca0d301 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/RtSimulationSubscribeMessageService.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/RtSimulationSubscribeMessageService.java @@ -1,11 +1,26 @@ package club.joylink.rtss.simulation.rt; +import club.joylink.rtss.exception.BusinessExceptionAssertEnum; +import club.joylink.rtss.simulation.Simulation; +import club.joylink.rtss.simulation.SimulationManager; import club.joylink.rtss.simulation.SimulationSubscribeMessageService; +import club.joylink.rtss.simulation.SimulationUser; +import club.joylink.rtss.simulation.rt.ATS.AtsLogicService; +import club.joylink.rtss.simulation.rt.ATS.bo.AtsRepository; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.util.List; + @Component public class RtSimulationSubscribeMessageService implements SimulationSubscribeMessageService { + @Autowired + private AtsLogicService atsLogicService; + + @Autowired + private SimulationManager simulationManager; + @Override public boolean acceptedSubscribePath(String destination) { return RtSimulationSubscribeTopic.hasMatched(destination); @@ -14,16 +29,12 @@ public class RtSimulationSubscribeMessageService implements SimulationSubscribeM @Override public Object buildMessageOfSubscribe(String destination) { RtSimulationSubscribeTopic topic = RtSimulationSubscribeTopic.match(destination); - return null; - } - - public void addJobs(RtSimulation rtSimulation) { - for (RtSimulationSubscribeTopic topic : RtSimulationSubscribeTopic.values()) { - rtSimulation.addJob("MESSAGE-" + topic.name(), () -> buildMessages(rtSimulation, topic), topic.getRate()); + String id = topic.getId(destination); + RtSimulation simulation = simulationManager.getById(id, RtSimulation.class); + switch (topic) { + case ATS: + return atsLogicService.getAllMessages(simulation); } - } - - public Object buildMessages(RtSimulation rtSimulation, RtSimulationSubscribeTopic topic) { return null; } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/RtSimulationSubscribeTopic.java b/src/main/java/club/joylink/rtss/simulation/rt/RtSimulationSubscribeTopic.java index dc034b078..1eeca4d4a 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/RtSimulationSubscribeTopic.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/RtSimulationSubscribeTopic.java @@ -1,5 +1,6 @@ package club.joylink.rtss.simulation.rt; +import club.joylink.rtss.simulation.Simulation; import club.joylink.rtss.simulation.rt.SRD.SrdLogicService; import lombok.Getter; import org.springframework.util.PropertyPlaceholderHelper; @@ -46,7 +47,8 @@ public enum RtSimulationSubscribeTopic { } public boolean isMatch(String destination) { - String[] patterns = StringUtils.tokenizeToStringArray(this.destPattern, PATH_SEPARATOR); + String destPattern = Simulation.MESSAGE_SUB_PREFIX + this.destPattern; + String[] patterns = StringUtils.tokenizeToStringArray(destPattern, PATH_SEPARATOR); String[] dests = StringUtils.tokenizeToStringArray(destination, PATH_SEPARATOR); if (patterns.length == dests.length) { for (int i = 0; i < patterns.length; i++) { @@ -64,7 +66,8 @@ public enum RtSimulationSubscribeTopic { } public String getId(String destination) { - String[] patterns = StringUtils.tokenizeToStringArray(this.destPattern, PATH_SEPARATOR); + String destPattern = Simulation.MESSAGE_SUB_PREFIX + this.destPattern; + String[] patterns = StringUtils.tokenizeToStringArray(destPattern, PATH_SEPARATOR); String[] dests = StringUtils.tokenizeToStringArray(destination, PATH_SEPARATOR); if (patterns.length == dests.length) { for (int i = 0; i < patterns.length; i++) { @@ -82,7 +85,8 @@ public enum RtSimulationSubscribeTopic { public String buildDestination(String simulationId) { Properties properties = new Properties(); properties.put("id", simulationId); - String dest = placeholderHelper.replacePlaceholders(this.destPattern, properties); + String dest = Simulation.MESSAGE_SUB_PREFIX + this.destPattern; + dest = placeholderHelper.replacePlaceholders(dest, properties); return dest; } } diff --git a/src/main/java/club/joylink/rtss/websocket/client/StompClientManager.java b/src/main/java/club/joylink/rtss/websocket/client/StompClientManager.java index 79881a579..bca561755 100644 --- a/src/main/java/club/joylink/rtss/websocket/client/StompClientManager.java +++ b/src/main/java/club/joylink/rtss/websocket/client/StompClientManager.java @@ -18,10 +18,10 @@ public class StompClientManager { WebSocketStompClient stompClient = new WebSocketStompClient(socketClient); SimulationSessionHandler handler = new SimulationSessionHandler(); ListenableFuture future = stompClient - .connect("ws://192.168.8.129:9000/joylink-websocket?token=aaa", + .connect("ws://192.168.3.120:9000/joylink-websocket?token=cc789dc2b2f003b2593f5eafbf4763bd", handler, "null"); StompSession stompSession = future.get(); - stompSession.subscribe("/user/queue/simulation/1/", handler); + stompSession.subscribe("/user/queue/simulation/11/ats", handler); } }