新版仿真ws消息推送实现
This commit is contained in:
parent
303760220a
commit
e15ed2db11
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -370,6 +370,10 @@ public abstract class Simulation<U extends SimulationUser, M extends Simulation
|
||||
return member;
|
||||
}
|
||||
|
||||
public List<M> getSimulationMembers() {
|
||||
return new ArrayList<>(this.simulationMemberMap.values());
|
||||
}
|
||||
|
||||
public List<M> querySimulationMembersOfRole(Object role) {
|
||||
return this.simulationMemberMap.values().stream()
|
||||
.filter(m -> Objects.equals(m.getRole(), role))
|
||||
|
@ -43,6 +43,11 @@ public class SimulationCommonController {
|
||||
this.simulationManager.updateSpeed(id, speed);
|
||||
}
|
||||
|
||||
@GetMapping("/{id}/members")
|
||||
public List<SimulationMember> 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<String, Object> params) {
|
||||
@ -54,6 +59,11 @@ public class SimulationCommonController {
|
||||
this.simulationManager.memberPlayedByUser(id, memberId, userId);
|
||||
}
|
||||
|
||||
@GetMapping("/{id}/users")
|
||||
public List<SimulationUser> getSimulationUsers(@PathVariable String id) {
|
||||
return this.simulationManager.getSimulationUsers(id);
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}/destroy")
|
||||
public void destroy(@PathVariable String id) {
|
||||
this.simulationManager.destroy(id);
|
||||
|
@ -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<Simulation> getSimulationList() {
|
||||
return new ArrayList<>(simulationCache.values());
|
||||
}
|
||||
|
||||
public List<SimulationMember> getSimulationMembers(String id) {
|
||||
Simulation simulation = getById(id);
|
||||
return simulation.getSimulationMembers();
|
||||
}
|
||||
|
||||
public List<SimulationUser> getSimulationUsers(String id) {
|
||||
Simulation simulation = getById(id);
|
||||
return simulation.getSimulationUsers();
|
||||
}
|
||||
}
|
||||
|
@ -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<String> 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) {
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<List<Object>> messages = repository.removeReady2SendMessages();
|
||||
if (!CollectionUtils.isEmpty(messages)) {
|
||||
List<SimulationUser> 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<List<Object>> getAllMessages(RtSimulation rtSimulation) {
|
||||
AtsRepository repository = rtSimulation.getRepository(AtsRepository.NAME, AtsRepository.class);
|
||||
return repository.getAllMessages();
|
||||
}
|
||||
}
|
||||
|
@ -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<String, List<Object>> messageMap = new HashMap<>();
|
||||
|
||||
Map<String, List<Object>> sendMessageMap = new HashMap<>();
|
||||
Map<String, List<Object>> ready2SendMessageMap = new HashMap<>();
|
||||
|
||||
Map<String, AtsRoute> routeMap = new HashMap<>();
|
||||
Map<String, AtsRunPlan> 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<Object> message = messageMap.get(id);
|
||||
if (message != null) {
|
||||
message.set(i, value);
|
||||
ready2SendMessageMap.putIfAbsent(id, message);
|
||||
}
|
||||
}
|
||||
|
||||
public List<List<Object>> removeReady2SendMessages() {
|
||||
ArrayList<List<Object>> messages = new ArrayList<>(this.ready2SendMessageMap.values());
|
||||
ready2SendMessageMap.clear();
|
||||
return messages;
|
||||
|
||||
}
|
||||
|
||||
public List<List<Object>> getAllMessages() {
|
||||
return new ArrayList<>(this.messageMap.values());
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<Object> buildMessage() {
|
||||
return Arrays.asList(id, position);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -67,6 +67,10 @@ public class CilRepository extends SimulationRepository {
|
||||
return cilSwitch;
|
||||
}
|
||||
|
||||
public List<CilSwitch> getSwitches() {
|
||||
return new ArrayList<>(switchMap.values());
|
||||
}
|
||||
|
||||
public CilSignal getSignalById(String id) {
|
||||
CilSignal cilSignal = this.signalMap.get(id);
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(cilSignal);
|
||||
|
@ -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<RtSimulationMember> memberList = rtSimulation.querySimulationMembersOfRole(RtSimulationMember.Role.LOWS);
|
||||
this.simulationManager.memberPlayedByUser(rtSimulation.getId(), memberList.get(0).getId(), rtSimulation.getCreator().getId());
|
||||
}
|
||||
List<RtSimulationMember> 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) {
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -18,10 +18,10 @@ public class StompClientManager {
|
||||
WebSocketStompClient stompClient = new WebSocketStompClient(socketClient);
|
||||
SimulationSessionHandler handler = new SimulationSessionHandler();
|
||||
ListenableFuture<StompSession> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user