Merge remote-tracking branch 'origin/develop' into develop

This commit is contained in:
thesai 2024-09-10 17:01:45 +08:00
commit 98abf0691a
2 changed files with 219 additions and 215 deletions

View File

@ -122,10 +122,12 @@ public class CgyStatsService {
public void syncUserSimulationUsing(UserSimulationRecordEvent event) { public void syncUserSimulationUsing(UserSimulationRecordEvent event) {
UserSimulationRecord record = event.getRecord(); UserSimulationRecord record = event.getRecord();
CgyStatsBO cgyStatsBO = functionStatsMap.get(record.getFunctionId()); CgyStatsBO cgyStatsBO = functionStatsMap.get(record.getFunctionId());
cgyStatsBO.getVisitor().incrementAndGet(); if (Objects.nonNull(cgyStatsBO)) {
cgyStatsBO.getUserSet().add(record.getUserId()); cgyStatsBO.getVisitor().incrementAndGet();
cgyStatsBO.getDuration().addAndGet(record.getDuration()); cgyStatsBO.getUserSet().add(record.getUserId());
cgyStatsBO.getChange().set(true); cgyStatsBO.getDuration().addAndGet(record.getDuration());
cgyStatsBO.getChange().set(true);
}
} }
/** /**

View File

@ -21,6 +21,7 @@ import club.joylink.rtss.vo.client.WebSocketMessageType;
import club.joylink.rtss.vo.client.factory.SocketMessageFactory; import club.joylink.rtss.vo.client.factory.SocketMessageFactory;
import club.joylink.rtss.websocket.StompMessageService; import club.joylink.rtss.websocket.StompMessageService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -33,14 +34,14 @@ import java.util.stream.Collectors;
@Component @Component
public class ATSMessageCollectAndDispatcher { public class ATSMessageCollectAndDispatcher {
@Autowired @Autowired
private Joylink3DMessageService joylink3DMessageService; private Joylink3DMessageService joylink3DMessageService;
@Autowired @Autowired
private StompMessageService stompMessageService; private StompMessageService stompMessageService;
@Autowired @Autowired
private ApplicationContext applicationContext; private ApplicationContext applicationContext;
// public void run(Simulation simulation) { // public void run(Simulation simulation) {
//// long start = System.currentTimeMillis(); //// long start = System.currentTimeMillis();
@ -62,222 +63,223 @@ public class ATSMessageCollectAndDispatcher {
//// System.out.println(String.format("收集并发送设备状态用时: [%s ms]", (end - start))); //// System.out.println(String.format("收集并发送设备状态用时: [%s ms]", (end - start)));
// } // }
/** /**
* 收集仿真所有设备状态并发送给仿真用户 * 收集仿真所有设备状态并发送给仿真用户
*/ */
public void collectAllAndSend(Simulation simulation) { public void collectAllAndSend(Simulation simulation) {
List<DeviceStatusVO> deviceStatuses = collectAll(simulation); List<DeviceStatusVO> deviceStatuses = collectAll(simulation);
// 构建并发送设备状态消息 // 构建并发送设备状态消息
SocketMessageVO<List<DeviceStatusVO>> deviceStatusMessage = SocketMessageVO<List<DeviceStatusVO>> deviceStatusMessage =
SocketMessageFactory.buildSimulationDeviceStatusesMessage(simulation.getId(), deviceStatuses); SocketMessageFactory.buildSimulationDeviceStatusesMessage(simulation.getId(), deviceStatuses);
Set<String> sessions = simulation.getSimulationUserIds(); Set<String> sessions = simulation.getSimulationUserIds();
stompMessageService.sendToUser(sessions, deviceStatusMessage); stompMessageService.sendToUser(sessions, deviceStatusMessage);
} }
/** /**
* 收集仿真所有设备状态 * 收集仿真所有设备状态
*/ */
public List<DeviceStatusVO> collectAll(Simulation simulation) { public List<DeviceStatusVO> collectAll(Simulation simulation) {
List<DeviceStatusVO> totalList = new ArrayList<>(); List<DeviceStatusVO> totalList = new ArrayList<>();
SimulationDataRepository repository = simulation.getRepository(); SimulationDataRepository repository = simulation.getRepository();
Map<String, ? extends MapElement> deviceMap = repository.getDeviceMap(); Map<String, ? extends MapElement> deviceMap = repository.getDeviceMap();
deviceMap.values().forEach(device -> { deviceMap.values().forEach(device -> {
DeviceStatus deviceStatus = repository.findStatusByCode(device.getCode()); DeviceStatus deviceStatus = repository.findStatusByCode(device.getCode());
if (Objects.isNull(deviceStatus)) { if (Objects.isNull(deviceStatus)) {
deviceStatus = buildDeviceStatus(device); deviceStatus = buildDeviceStatus(device);
if (Objects.nonNull(deviceStatus)) { if (Objects.nonNull(deviceStatus)) {
repository.addDeviceInfo(deviceStatus); repository.addDeviceInfo(deviceStatus);
totalList.add(deviceStatus.convert2VO(device)); totalList.add(deviceStatus.convert2VO(device));
} }
} else { } else {
DeviceStatusVO statusVO = buildDeviceStatusVO(device); DeviceStatusVO statusVO = buildDeviceStatusVO(device);
if (deviceStatus.compareAndChange(device, statusVO)) { if (deviceStatus.compareAndChange(device, statusVO)) {
totalList.add(statusVO); totalList.add(statusVO);
} }
} }
}); });
// 列车状态 // 列车状态
List<TrainInfo> trainList = repository.getSuperviseTrainList(); List<TrainInfo> trainList = repository.getSuperviseTrainList();
trainList.forEach(train -> { trainList.forEach(train -> {
TrainStatus trainStatus = repository.findStatusByCode(train.getGroupNumber(), TrainStatus.class); TrainStatus trainStatus = repository.findStatusByCode(train.getGroupNumber(), TrainStatus.class);
if (Objects.isNull(trainStatus)) { if (Objects.isNull(trainStatus)) {
// if(simulation.getBuildParams().getProdType() == MapPrdTypeEnum.YJDDZH){ // if(simulation.getBuildParams().getProdType() == MapPrdTypeEnum.YJDDZH){
if(Objects.equals(simulation.getProject(),MapPrdTypeEnum.YJDDZH.name())){ if (Objects.equals(simulation.getProject(), MapPrdTypeEnum.YJDDZH.name())) {
trainStatus = new YJDDZHTrainStatus(train); trainStatus = new YJDDZHTrainStatus(train);
}else{ } else {
trainStatus = new TrainStatus(train); trainStatus = new TrainStatus(train);
} }
repository.addDeviceInfo(trainStatus); repository.addDeviceInfo(trainStatus);
totalList.add(trainStatus.convert2VO(train)); totalList.add(trainStatus.convert2VO(train));
} else { } else {
DeviceStatusVO statusVO; DeviceStatusVO statusVO;
// if(simulation.getBuildParams().getProdType() == MapPrdTypeEnum.YJDDZH){ // if(simulation.getBuildParams().getProdType() == MapPrdTypeEnum.YJDDZH){
if(Objects.equals(simulation.getProject(),MapPrdTypeEnum.YJDDZH.name())){ if (Objects.equals(simulation.getProject(), MapPrdTypeEnum.YJDDZH.name())) {
statusVO = new YJDDZHTrainStatusVO(train); statusVO = new YJDDZHTrainStatusVO(train);
}else{ } else {
statusVO = new TrainStatusVO(train); // statusVO = new TrainStatusVO(train);
} statusVO = new TrainStatusVO(trainStatus);
if (trainStatus.compareAndChange(train, statusVO)) {
totalList.add(statusVO);
}
}
});
// 回库删除的列车状态
List<TrainStatus> inboundTrainList = new ArrayList<>();
List<TrainStatus> trainStatusList = repository.getTrainStatusList();
if (!CollectionUtils.isEmpty(trainStatusList)) {
for (TrainStatus trainStatus : trainStatusList) {
TrainInfo trainInfo = repository.findSupervisedTrainByGroup(trainStatus.getGroupNumber());
if (Objects.isNull(trainInfo)) {
totalList.add(TrainStatusVO.buildDispose(trainStatus.getGroupNumber()));
inboundTrainList.add(trainStatus);
repository.deleteDeviceStatus(trainStatus.getCode());
}
}
} }
joylink3DMessageService.handleTrainInbound(simulation, inboundTrainList); if (trainStatus.compareAndChange(train, statusVO)) {
return totalList; totalList.add(statusVO);
}
private DeviceStatus buildDeviceStatus(MapElement device) {
DeviceStatus status = null;
switch (device.getDeviceType()) {
case SECTION:
status = new SectionStatus((Section) device);
break;
case SWITCH:
status = new SwitchStatus((Switch) device);
break;
case SIGNAL:
status = new SignalStatus((Signal) device);
break;
case STATION:
status = new StationStatus((Station) device);
break;
case STAND:
status = new StandStatus((Stand) device);
break;
case PSD:
status = new PSDStatus((PSD) device);
break;
case ZC:
status = new ZCStatus((ZC) device);
break;
case ROUTE:
status = new RouteStatus((Route) device);
break;
case OVERLAP: {
status = new OverlapStatus((RouteOverlap) device);
break;
}
case CYCLE:
status = new CycleStatus((Cycle) device);
break;
case DIRECTION_ROD:
status = new DirectionRodStatus((DirectionRod) device);
break;
case CATENARY:
status = new CatenaryStatus((Catenary) device);
break;
case STATION_DIRECTION:
status = new StationDirectionStatus((StationDirection) device);
break;
} }
return status; }
} });
// 回库删除的列车状态
private DeviceStatusVO buildDeviceStatusVO(MapElement device) { List<TrainStatus> inboundTrainList = new ArrayList<>();
DeviceStatusVO status = null; List<TrainStatus> trainStatusList = repository.getTrainStatusList();
switch (device.getDeviceType()) { if (!CollectionUtils.isEmpty(trainStatusList)) {
case SECTION: for (TrainStatus trainStatus : trainStatusList) {
status = new SectionStatusVO((Section) device); TrainInfo trainInfo = repository.findSupervisedTrainByGroup(trainStatus.getGroupNumber());
break; if (Objects.isNull(trainInfo)) {
case SWITCH: totalList.add(TrainStatusVO.buildDispose(trainStatus.getGroupNumber()));
status = new SwitchStatusVO((Switch) device); inboundTrainList.add(trainStatus);
break; repository.deleteDeviceStatus(trainStatus.getCode());
case SIGNAL:
status = new SignalStatusVO((Signal) device);
break;
case STATION:
status = new StationStatusVO((Station) device);
break;
case STAND:
status = new StandStatusVO((Stand) device);
break;
case PSD:
status = new PSDStatusVO((PSD) device);
break;
case ZC:
status = new ZCStatusVO((ZC) device);
break;
case ROUTE:
status = new RouteStatusVO((Route) device);
break;
case OVERLAP: {
status = new OverlapStatusVO((RouteOverlap) device);
break;
}
case CYCLE:
status = new CycleStatusVO((Cycle) device);
break;
case DIRECTION_ROD:
status = new DirectionRodStatusVO((DirectionRod) device);
break;
case CATENARY:
status = new CatenaryStatusVO((Catenary) device);
break;
case STATION_DIRECTION:
status = new StationDirectionStatusVO((StationDirection) device);
break;
} }
return status; }
} }
joylink3DMessageService.handleTrainInbound(simulation, inboundTrainList);
return totalList;
}
/** private DeviceStatus buildDeviceStatus(MapElement device) {
* 列车运行数据 DeviceStatus status = null;
*/ switch (device.getDeviceType()) {
public void sendTrainRunData(Simulation simulation, RealRun realRun) { case SECTION:
stompMessageService.sendToUser(simulation.getSimulationUserIds(), status = new SectionStatus((Section) device);
SocketMessageFactory.build(WebSocketMessageType.Simulation_RunFact, break;
simulation.getId(), Arrays.asList(realRun))); case SWITCH:
} status = new SwitchStatus((Switch) device);
break;
case SIGNAL:
status = new SignalStatus((Signal) device);
break;
case STATION:
status = new StationStatus((Station) device);
break;
case STAND:
status = new StandStatus((Stand) device);
break;
case PSD:
status = new PSDStatus((PSD) device);
break;
case ZC:
status = new ZCStatus((ZC) device);
break;
case ROUTE:
status = new RouteStatus((Route) device);
break;
case OVERLAP: {
status = new OverlapStatus((RouteOverlap) device);
break;
}
case CYCLE:
status = new CycleStatus((Cycle) device);
break;
case DIRECTION_ROD:
status = new DirectionRodStatus((DirectionRod) device);
break;
case CATENARY:
status = new CatenaryStatus((Catenary) device);
break;
/** case STATION_DIRECTION:
* 仿真设备操作消息 status = new StationDirectionStatus((StationDirection) device);
*/ break;
public void handlerOperateMessage(Simulation simulation, OperationMessage operationMessage) {
SocketMessageVO<OperationMessage> socketMessageVO =
SocketMessageFactory.build(WebSocketMessageType.Simulation_ApplyHandle, simulation.getId(), operationMessage);
Set<SimulationMember> humanMembers = operationMessage.getTargetMembers().stream().filter(m -> !m.isRobot()).collect(Collectors.toSet());
//当在场景实训设计中并且无真人成员时将数据暂存等待后续角色有人扮演时再发送
if (simulation.isInSceneTraining() && CollectionUtils.isEmpty(humanMembers)) {
for (SimulationMember targetMember : operationMessage.getTargetMembers()) {
targetMember.getUnreceivedMessages().offer(socketMessageVO);
}
return;
}
if (CollectionUtils.isEmpty(humanMembers)) {
//目标都是机器人选择一个机器人发送事件处理
applicationContext.publishEvent(new SimulationOperationMessageEvent(this, simulation, operationMessage));
return;
}
//目标成员有真人推送对应真人处理
stompMessageService.sendToUser(humanMembers.stream().map(SimulationMember::getUserId).collect(Collectors.toSet()), socketMessageVO);
} }
return status;
}
/** private DeviceStatusVO buildDeviceStatusVO(MapElement device) {
* 同步仿真系统时间给客户端 DeviceStatusVO status = null;
*/ switch (device.getDeviceType()) {
public void syncTime(Simulation simulation) { case SECTION:
Set<String> sessions = simulation.getSimulationUserIds(); status = new SectionStatusVO((Section) device);
SocketMessageVO<Long> timeSyncMessage = SocketMessageFactory.buildSimulationTimeSyncMessage(simulation); break;
stompMessageService.sendToUser(sessions, timeSyncMessage); case SWITCH:
} status = new SwitchStatusVO((Switch) device);
break;
case SIGNAL:
status = new SignalStatusVO((Signal) device);
break;
case STATION:
status = new StationStatusVO((Station) device);
break;
case STAND:
status = new StandStatusVO((Stand) device);
break;
case PSD:
status = new PSDStatusVO((PSD) device);
break;
case ZC:
status = new ZCStatusVO((ZC) device);
break;
case ROUTE:
status = new RouteStatusVO((Route) device);
break;
case OVERLAP: {
status = new OverlapStatusVO((RouteOverlap) device);
break;
}
case CYCLE:
status = new CycleStatusVO((Cycle) device);
break;
case DIRECTION_ROD:
status = new DirectionRodStatusVO((DirectionRod) device);
break;
case CATENARY:
status = new CatenaryStatusVO((Catenary) device);
break;
public void addJobs(Simulation simulation) { case STATION_DIRECTION:
simulation.addJob(SimulationModule.SYNC_TIME.name(), () -> syncTime(simulation), SimulationConstants.SYNC_TIME_RATE); status = new StationDirectionStatusVO((StationDirection) device);
simulation.addFixedRateJob(SimulationModule.MESSAGE.name(), () -> collectAllAndSend(simulation), SimulationConstants.SEND_CLIENT_RATE); break;
} }
return status;
}
/**
* 列车运行数据
*/
public void sendTrainRunData(Simulation simulation, RealRun realRun) {
stompMessageService.sendToUser(simulation.getSimulationUserIds(),
SocketMessageFactory.build(WebSocketMessageType.Simulation_RunFact,
simulation.getId(), Arrays.asList(realRun)));
}
/**
* 仿真设备操作消息
*/
public void handlerOperateMessage(Simulation simulation, OperationMessage operationMessage) {
SocketMessageVO<OperationMessage> socketMessageVO =
SocketMessageFactory.build(WebSocketMessageType.Simulation_ApplyHandle, simulation.getId(), operationMessage);
Set<SimulationMember> humanMembers = operationMessage.getTargetMembers().stream().filter(m -> !m.isRobot()).collect(Collectors.toSet());
//当在场景实训设计中并且无真人成员时将数据暂存等待后续角色有人扮演时再发送
if (simulation.isInSceneTraining() && CollectionUtils.isEmpty(humanMembers)) {
for (SimulationMember targetMember : operationMessage.getTargetMembers()) {
targetMember.getUnreceivedMessages().offer(socketMessageVO);
}
return;
}
if (CollectionUtils.isEmpty(humanMembers)) {
//目标都是机器人选择一个机器人发送事件处理
applicationContext.publishEvent(new SimulationOperationMessageEvent(this, simulation, operationMessage));
return;
}
//目标成员有真人推送对应真人处理
stompMessageService.sendToUser(humanMembers.stream().map(SimulationMember::getUserId).collect(Collectors.toSet()), socketMessageVO);
}
/**
* 同步仿真系统时间给客户端
*/
public void syncTime(Simulation simulation) {
Set<String> sessions = simulation.getSimulationUserIds();
SocketMessageVO<Long> timeSyncMessage = SocketMessageFactory.buildSimulationTimeSyncMessage(simulation);
stompMessageService.sendToUser(sessions, timeSyncMessage);
}
public void addJobs(Simulation simulation) {
simulation.addJob(SimulationModule.SYNC_TIME.name(), () -> syncTime(simulation), SimulationConstants.SYNC_TIME_RATE);
simulation.addFixedRateJob(SimulationModule.MESSAGE.name(), () -> collectAllAndSend(simulation), SimulationConstants.SEND_CLIENT_RATE);
}
} }