Merge remote-tracking branch 'origin/develop' into develop
This commit is contained in:
commit
98abf0691a
|
@ -122,10 +122,12 @@ public class CgyStatsService {
|
|||
public void syncUserSimulationUsing(UserSimulationRecordEvent event) {
|
||||
UserSimulationRecord record = event.getRecord();
|
||||
CgyStatsBO cgyStatsBO = functionStatsMap.get(record.getFunctionId());
|
||||
cgyStatsBO.getVisitor().incrementAndGet();
|
||||
cgyStatsBO.getUserSet().add(record.getUserId());
|
||||
cgyStatsBO.getDuration().addAndGet(record.getDuration());
|
||||
cgyStatsBO.getChange().set(true);
|
||||
if (Objects.nonNull(cgyStatsBO)) {
|
||||
cgyStatsBO.getVisitor().incrementAndGet();
|
||||
cgyStatsBO.getUserSet().add(record.getUserId());
|
||||
cgyStatsBO.getDuration().addAndGet(record.getDuration());
|
||||
cgyStatsBO.getChange().set(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,6 +21,7 @@ import club.joylink.rtss.vo.client.WebSocketMessageType;
|
|||
import club.joylink.rtss.vo.client.factory.SocketMessageFactory;
|
||||
import club.joylink.rtss.websocket.StompMessageService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
@ -33,14 +34,14 @@ import java.util.stream.Collectors;
|
|||
@Component
|
||||
public class ATSMessageCollectAndDispatcher {
|
||||
|
||||
@Autowired
|
||||
private Joylink3DMessageService joylink3DMessageService;
|
||||
@Autowired
|
||||
private Joylink3DMessageService joylink3DMessageService;
|
||||
|
||||
@Autowired
|
||||
private StompMessageService stompMessageService;
|
||||
@Autowired
|
||||
private StompMessageService stompMessageService;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
// public void run(Simulation simulation) {
|
||||
//// long start = System.currentTimeMillis();
|
||||
|
@ -62,222 +63,223 @@ public class ATSMessageCollectAndDispatcher {
|
|||
//// System.out.println(String.format("收集并发送设备状态用时: [%s ms]", (end - start)));
|
||||
// }
|
||||
|
||||
/**
|
||||
* 收集仿真所有设备状态并发送给仿真用户
|
||||
*/
|
||||
public void collectAllAndSend(Simulation simulation) {
|
||||
List<DeviceStatusVO> deviceStatuses = collectAll(simulation);
|
||||
// 构建并发送设备状态消息
|
||||
SocketMessageVO<List<DeviceStatusVO>> deviceStatusMessage =
|
||||
SocketMessageFactory.buildSimulationDeviceStatusesMessage(simulation.getId(), deviceStatuses);
|
||||
Set<String> sessions = simulation.getSimulationUserIds();
|
||||
stompMessageService.sendToUser(sessions, deviceStatusMessage);
|
||||
}
|
||||
/**
|
||||
* 收集仿真所有设备状态并发送给仿真用户
|
||||
*/
|
||||
public void collectAllAndSend(Simulation simulation) {
|
||||
List<DeviceStatusVO> deviceStatuses = collectAll(simulation);
|
||||
// 构建并发送设备状态消息
|
||||
SocketMessageVO<List<DeviceStatusVO>> deviceStatusMessage =
|
||||
SocketMessageFactory.buildSimulationDeviceStatusesMessage(simulation.getId(), deviceStatuses);
|
||||
Set<String> sessions = simulation.getSimulationUserIds();
|
||||
stompMessageService.sendToUser(sessions, deviceStatusMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 收集仿真所有设备状态
|
||||
*/
|
||||
public List<DeviceStatusVO> collectAll(Simulation simulation) {
|
||||
List<DeviceStatusVO> totalList = new ArrayList<>();
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
Map<String, ? extends MapElement> deviceMap = repository.getDeviceMap();
|
||||
deviceMap.values().forEach(device -> {
|
||||
DeviceStatus deviceStatus = repository.findStatusByCode(device.getCode());
|
||||
if (Objects.isNull(deviceStatus)) {
|
||||
deviceStatus = buildDeviceStatus(device);
|
||||
if (Objects.nonNull(deviceStatus)) {
|
||||
repository.addDeviceInfo(deviceStatus);
|
||||
totalList.add(deviceStatus.convert2VO(device));
|
||||
}
|
||||
} else {
|
||||
DeviceStatusVO statusVO = buildDeviceStatusVO(device);
|
||||
if (deviceStatus.compareAndChange(device, statusVO)) {
|
||||
totalList.add(statusVO);
|
||||
}
|
||||
}
|
||||
});
|
||||
// 列车状态
|
||||
List<TrainInfo> trainList = repository.getSuperviseTrainList();
|
||||
trainList.forEach(train -> {
|
||||
TrainStatus trainStatus = repository.findStatusByCode(train.getGroupNumber(), TrainStatus.class);
|
||||
if (Objects.isNull(trainStatus)) {
|
||||
/**
|
||||
* 收集仿真所有设备状态
|
||||
*/
|
||||
public List<DeviceStatusVO> collectAll(Simulation simulation) {
|
||||
List<DeviceStatusVO> totalList = new ArrayList<>();
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
Map<String, ? extends MapElement> deviceMap = repository.getDeviceMap();
|
||||
deviceMap.values().forEach(device -> {
|
||||
DeviceStatus deviceStatus = repository.findStatusByCode(device.getCode());
|
||||
if (Objects.isNull(deviceStatus)) {
|
||||
deviceStatus = buildDeviceStatus(device);
|
||||
if (Objects.nonNull(deviceStatus)) {
|
||||
repository.addDeviceInfo(deviceStatus);
|
||||
totalList.add(deviceStatus.convert2VO(device));
|
||||
}
|
||||
} else {
|
||||
DeviceStatusVO statusVO = buildDeviceStatusVO(device);
|
||||
if (deviceStatus.compareAndChange(device, statusVO)) {
|
||||
totalList.add(statusVO);
|
||||
}
|
||||
}
|
||||
});
|
||||
// 列车状态
|
||||
List<TrainInfo> trainList = repository.getSuperviseTrainList();
|
||||
trainList.forEach(train -> {
|
||||
TrainStatus trainStatus = repository.findStatusByCode(train.getGroupNumber(), TrainStatus.class);
|
||||
if (Objects.isNull(trainStatus)) {
|
||||
// if(simulation.getBuildParams().getProdType() == MapPrdTypeEnum.YJDDZH){
|
||||
if(Objects.equals(simulation.getProject(),MapPrdTypeEnum.YJDDZH.name())){
|
||||
trainStatus = new YJDDZHTrainStatus(train);
|
||||
}else{
|
||||
trainStatus = new TrainStatus(train);
|
||||
}
|
||||
repository.addDeviceInfo(trainStatus);
|
||||
totalList.add(trainStatus.convert2VO(train));
|
||||
} else {
|
||||
DeviceStatusVO statusVO;
|
||||
if (Objects.equals(simulation.getProject(), MapPrdTypeEnum.YJDDZH.name())) {
|
||||
trainStatus = new YJDDZHTrainStatus(train);
|
||||
} else {
|
||||
trainStatus = new TrainStatus(train);
|
||||
}
|
||||
repository.addDeviceInfo(trainStatus);
|
||||
totalList.add(trainStatus.convert2VO(train));
|
||||
} else {
|
||||
DeviceStatusVO statusVO;
|
||||
// if(simulation.getBuildParams().getProdType() == MapPrdTypeEnum.YJDDZH){
|
||||
if(Objects.equals(simulation.getProject(),MapPrdTypeEnum.YJDDZH.name())){
|
||||
statusVO = new YJDDZHTrainStatusVO(train);
|
||||
}else{
|
||||
statusVO = new TrainStatusVO(train);
|
||||
}
|
||||
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());
|
||||
}
|
||||
}
|
||||
if (Objects.equals(simulation.getProject(), MapPrdTypeEnum.YJDDZH.name())) {
|
||||
statusVO = new YJDDZHTrainStatusVO(train);
|
||||
} else {
|
||||
// statusVO = new TrainStatusVO(train);
|
||||
statusVO = new TrainStatusVO(trainStatus);
|
||||
}
|
||||
joylink3DMessageService.handleTrainInbound(simulation, inboundTrainList);
|
||||
return totalList;
|
||||
}
|
||||
|
||||
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;
|
||||
if (trainStatus.compareAndChange(train, statusVO)) {
|
||||
totalList.add(statusVO);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
private DeviceStatusVO buildDeviceStatusVO(MapElement device) {
|
||||
DeviceStatusVO status = null;
|
||||
switch (device.getDeviceType()) {
|
||||
case SECTION:
|
||||
status = new SectionStatusVO((Section) device);
|
||||
break;
|
||||
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;
|
||||
|
||||
case STATION_DIRECTION:
|
||||
status = new StationDirectionStatusVO((StationDirection) device);
|
||||
break;
|
||||
}
|
||||
});
|
||||
// 回库删除的列车状态
|
||||
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());
|
||||
}
|
||||
return status;
|
||||
}
|
||||
}
|
||||
joylink3DMessageService.handleTrainInbound(simulation, inboundTrainList);
|
||||
return totalList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 列车运行数据
|
||||
*/
|
||||
public void sendTrainRunData(Simulation simulation, RealRun realRun) {
|
||||
stompMessageService.sendToUser(simulation.getSimulationUserIds(),
|
||||
SocketMessageFactory.build(WebSocketMessageType.Simulation_RunFact,
|
||||
simulation.getId(), Arrays.asList(realRun)));
|
||||
}
|
||||
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;
|
||||
|
||||
/**
|
||||
* 仿真设备操作消息
|
||||
*/
|
||||
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);
|
||||
case STATION_DIRECTION:
|
||||
status = new StationDirectionStatus((StationDirection) device);
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步仿真系统时间给客户端
|
||||
*/
|
||||
public void syncTime(Simulation simulation) {
|
||||
Set<String> sessions = simulation.getSimulationUserIds();
|
||||
SocketMessageVO<Long> timeSyncMessage = SocketMessageFactory.buildSimulationTimeSyncMessage(simulation);
|
||||
stompMessageService.sendToUser(sessions, timeSyncMessage);
|
||||
}
|
||||
private DeviceStatusVO buildDeviceStatusVO(MapElement device) {
|
||||
DeviceStatusVO status = null;
|
||||
switch (device.getDeviceType()) {
|
||||
case SECTION:
|
||||
status = new SectionStatusVO((Section) device);
|
||||
break;
|
||||
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) {
|
||||
simulation.addJob(SimulationModule.SYNC_TIME.name(), () -> syncTime(simulation), SimulationConstants.SYNC_TIME_RATE);
|
||||
simulation.addFixedRateJob(SimulationModule.MESSAGE.name(), () -> collectAllAndSend(simulation), SimulationConstants.SEND_CLIENT_RATE);
|
||||
case STATION_DIRECTION:
|
||||
status = new StationDirectionStatusVO((StationDirection) device);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue