Merge remote-tracking branch 'origin/test' into dev

# Conflicts:
#	src/main/java/club/joylink/rtss/services/VirtualRealityIbpService.java
This commit is contained in:
joylink_zhangsai 2021-06-18 09:12:47 +08:00
commit 4929e21076
13 changed files with 135 additions and 35 deletions

View File

@ -34,31 +34,31 @@ public class SimulationManageServiceImpl implements SimulationManageService {
@Autowired @Autowired
private GroupSimulationService groupSimulationService; private GroupSimulationService groupSimulationService;
//
@Scheduled(fixedRate = 500) // @Scheduled(fixedRate = 500)
public void deleteUselessSimulation() { // public void deleteUselessSimulation() {
Map<String, Simulation> groupSimulationMap = this.groupSimulationCache.getGroupSimulationMap(); // Map<String, Simulation> groupSimulationMap = this.groupSimulationCache.getGroupSimulationMap();
groupSimulationMap.forEach((group, simulation) -> { // groupSimulationMap.forEach((group, simulation) -> {
List<SimulationUser> userList = simulation.getSimulationUsers(); // List<SimulationUser> userList = simulation.getSimulationUsers();
boolean hasOnline = false; // boolean hasOnline = false;
for (SimulationUser simulationUser : userList) { // for (SimulationUser simulationUser : userList) {
if (simulationUser.isOnline()) { // if (simulationUser.isOnline()) {
hasOnline = true; // hasOnline = true;
break; // break;
} // }
} // }
LocalDateTime delBaseTime = simulation.getDelBaseTime(); // LocalDateTime delBaseTime = simulation.getDelBaseTime();
if (hasOnline && Objects.nonNull(delBaseTime)) { // if (hasOnline && Objects.nonNull(delBaseTime)) {
simulation.setDelBaseTime(null); // simulation.setDelBaseTime(null);
} else if (!hasOnline && Objects.isNull(delBaseTime)) { // } else if (!hasOnline && Objects.isNull(delBaseTime)) {
simulation.setDelBaseTime(LocalDateTime.now()); // simulation.setDelBaseTime(LocalDateTime.now());
} else if (!hasOnline && Objects.nonNull(delBaseTime)) { // } else if (!hasOnline && Objects.nonNull(delBaseTime)) {
if (LocalDateTime.now().isAfter(delBaseTime.plusMinutes(3))) { // if (LocalDateTime.now().isAfter(delBaseTime.plusMinutes(3))) {
this.destroySimulation(group, simulation.getCreator()); // this.destroySimulation(group, simulation.getCreator());
} // }
} // }
}); // });
} // }
@Override @Override
public PageVO<SimulationVO> pagingQueryExistSimulations(ExistSimulationQueryVO queryVO) { public PageVO<SimulationVO> pagingQueryExistSimulations(ExistSimulationQueryVO queryVO) {

View File

@ -56,6 +56,10 @@ public abstract class Simulation<U extends SimulationUser, M extends Simulation
private static final int PAUSE = 0; private static final int PAUSE = 0;
private static final int ERROR = 4; private static final int ERROR = 4;
private static final int DESTROY = 7; private static final int DESTROY = 7;
/**
* 所有用户都没有订阅仿真开始时间
*/
private LocalDateTime noUserStartTime;
/** /**
* 仿真运行发生异常时保存的异常信息 * 仿真运行发生异常时保存的异常信息
*/ */
@ -329,6 +333,7 @@ public abstract class Simulation<U extends SimulationUser, M extends Simulation
* 仿真销毁时调用用于清除定时执行逻辑对象 * 仿真销毁时调用用于清除定时执行逻辑对象
*/ */
public void destroy() { public void destroy() {
log.debug(String.format("仿真[%s]销毁", this.id));
this.future.cancel(true); this.future.cancel(true);
this.updateState(DESTROY); this.updateState(DESTROY);
} }
@ -425,6 +430,9 @@ public abstract class Simulation<U extends SimulationUser, M extends Simulation
} }
public void addSimulationUser(U user) { public void addSimulationUser(U user) {
if (this.simulationUserMap.isEmpty()) {
user.creator = true;
}
this.simulationUserMap.put(user.getId(), user); this.simulationUserMap.put(user.getId(), user);
} }
@ -576,4 +584,8 @@ public abstract class Simulation<U extends SimulationUser, M extends Simulation
this.operationList.add(memberOperation); this.operationList.add(memberOperation);
} }
} }
public void setNoUserStartTime(LocalDateTime noUserStartTime) {
this.noUserStartTime = noUserStartTime;
}
} }

View File

@ -27,9 +27,10 @@ public class SimulationCommonController {
@GetMapping("/list") @GetMapping("/list")
public List<SimulationInfoVO> queryInfo() { public List<SimulationInfoVO> queryInfo() {
List<Simulation> simulationList = this.simulationManager.getSimulationList(); List<Simulation> simulationList = this.simulationManager.getSimulationList();
return simulationList.stream() List<SimulationInfoVO> list = simulationList.stream()
.map(Simulation::convertToVO) .map(Simulation::convertToVO)
.collect(Collectors.toList()); .collect(Collectors.toList());
return list;
} }
@PutMapping("/{id}/pause") @PutMapping("/{id}/pause")

View File

@ -5,13 +5,17 @@ import club.joylink.rtss.simulation.event.SimulationFaultInjectEvent;
import club.joylink.rtss.simulation.event.SimulationFaultRemoveEvent; import club.joylink.rtss.simulation.event.SimulationFaultRemoveEvent;
import club.joylink.rtss.simulation.event.SimulationMemberPlayChangeEvent; import club.joylink.rtss.simulation.event.SimulationMemberPlayChangeEvent;
import club.joylink.rtss.simulation.messaging.websocket.DefaultMessageSender; import club.joylink.rtss.simulation.messaging.websocket.DefaultMessageSender;
import club.joylink.rtss.simulation.rt.RtSimulation;
import club.joylink.rtss.simulation.rt.RtSimulationUser;
import club.joylink.rtss.simulation.vo.SimulationFaultVO; import club.joylink.rtss.simulation.vo.SimulationFaultVO;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
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.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -27,6 +31,35 @@ public class SimulationManager {
@Autowired @Autowired
private DefaultMessageSender defaultMessageSender; private DefaultMessageSender defaultMessageSender;
public static final int Destroy_Time = 180; // RtSimulation无用户时销毁时间单位s
@Scheduled(fixedRate = 5000)
public void cleanUselessRtSimulation() {
simulationCache.values().stream()
.forEach(simulation -> {
boolean hasSubUser = false;
for (Object su : simulation.getSimulationUsers()) {
SimulationUser simulationUser = (SimulationUser) su;
if (simulationUser.hasSubscribe()) {
hasSubUser = true;
break;
}
}
LocalDateTime noUserStartTime = simulation.getNoUserStartTime();
if (hasSubUser) {
if (noUserStartTime != null) {
simulation.setNoUserStartTime(null);
}
} else {
LocalDateTime now = LocalDateTime.now();
if (noUserStartTime == null) {
simulation.setNoUserStartTime(now);
} else if (noUserStartTime.plusSeconds(Destroy_Time).isBefore(now)) {
this.destroy(simulation.getId());
}
}
});
}
public Simulation save(Simulation simulation) { public Simulation save(Simulation simulation) {
BusinessExceptionAssertEnum.DATA_ALREADY_EXIST.assertNotTrue(simulationCache.containsKey(simulation.getId()), BusinessExceptionAssertEnum.DATA_ALREADY_EXIST.assertNotTrue(simulationCache.containsKey(simulation.getId()),
String.format("已经存在id为[%s]的仿真[%s]", simulation.getId(), simulation.debugStr())); String.format("已经存在id为[%s]的仿真[%s]", simulation.getId(), simulation.debugStr()));

View File

@ -15,6 +15,8 @@ public abstract class SimulationUser {
* 仿真用户唯一标识并且是发布订阅消息时的用户唯一标识 * 仿真用户唯一标识并且是发布订阅消息时的用户唯一标识
*/ */
private String id; private String id;
private String name;
boolean creator;
/** /**
* 用户仿真消息订阅 * 用户仿真消息订阅
* key-wsSessionId * key-wsSessionId
@ -24,14 +26,23 @@ public abstract class SimulationUser {
private String memberId; // 扮演的成员id private String memberId; // 扮演的成员id
public SimulationUser(String id) { public SimulationUser(String id, String name) {
this.id = id; this.id = id;
this.name = name;
} }
public String getId() { public String getId() {
return id; return id;
} }
public String getName() {
return name;
}
public boolean isCreator() {
return creator;
}
public String getMemberId() { public String getMemberId() {
return memberId; return memberId;
} }
@ -65,6 +76,10 @@ public abstract class SimulationUser {
return false; return false;
} }
public boolean hasSubscribe() {
return !this.wsSubscribeMap.isEmpty();
}
public void disconnect(String wsSessionId) { public void disconnect(String wsSessionId) {
this.wsSubscribeMap.remove(wsSessionId); this.wsSubscribeMap.remove(wsSessionId);
log.debug(String.format("用户[%s]断开了连接[%s]", this.id, wsSessionId)); log.debug(String.format("用户[%s]断开了连接[%s]", this.id, wsSessionId));

View File

@ -13,6 +13,7 @@ import club.joylink.rtss.simulation.cbtc.conversation.Conversation;
import club.joylink.rtss.simulation.cbtc.conversation.ConversationMember; import club.joylink.rtss.simulation.cbtc.conversation.ConversationMember;
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository; import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
import club.joylink.rtss.simulation.cbtc.data.map.MapElement; import club.joylink.rtss.simulation.cbtc.data.map.MapElement;
import club.joylink.rtss.simulation.cbtc.data.vo.OldSimulationInfoVO;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.DeviceQueryFuture; import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.DeviceQueryFuture;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.device.PlcGateway; import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.device.PlcGateway;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.device.RealDeviceConfig; import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.device.RealDeviceConfig;
@ -391,7 +392,7 @@ public class Simulation extends club.joylink.rtss.simulation.Simulation<Simulati
@Override @Override
public SimulationInfoVO buildVO() { public SimulationInfoVO buildVO() {
return null; return new OldSimulationInfoVO(this);
} }
public void addLog(SimulationLog log) { public void addLog(SimulationLog log) {

View File

@ -0,0 +1,20 @@
package club.joylink.rtss.simulation.cbtc.data.vo;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.build.SimulationBuildParams;
import club.joylink.rtss.simulation.vo.SimulationInfoVO;
import club.joylink.rtss.vo.map.MapVO;
import lombok.Getter;
@Getter
public class OldSimulationInfoVO extends SimulationInfoVO {
private String prodType;
private MapVO map;
public OldSimulationInfoVO(Simulation simulation) {
super(simulation);
SimulationBuildParams buildParams = simulation.getBuildParams();
this.prodType = buildParams.getProdType().getCode();
this.map = buildParams.getMap().buildBasicInfo();
}
}

View File

@ -43,7 +43,7 @@ public class SimulationUser extends club.joylink.rtss.simulation.SimulationUser
private SimulationMember playedMember; private SimulationMember playedMember;
public SimulationUser(Simulation simulation, LoginUserInfoVO loginUserInfoVO) { public SimulationUser(Simulation simulation, LoginUserInfoVO loginUserInfoVO) {
super(String.valueOf(loginUserInfoVO.getAccountVO().getId())); super(String.valueOf(loginUserInfoVO.getAccountVO().getId()), loginUserInfoVO.getAccountVO().getNickname());
this.group = simulation.getId(); this.group = simulation.getId();
this.user = loginUserInfoVO.getAccountVO(); this.user = loginUserInfoVO.getAccountVO();
this.projectDevice = loginUserInfoVO.getDeviceVO(); this.projectDevice = loginUserInfoVO.getDeviceVO();
@ -56,7 +56,7 @@ public class SimulationUser extends club.joylink.rtss.simulation.SimulationUser
} }
public SimulationUser(Simulation simulation, AccountVO user) { public SimulationUser(Simulation simulation, AccountVO user) {
super(user.getId().toString()); super(user.getId().toString(), user.getNickname());
this.group = simulation.getId(); this.group = simulation.getId();
this.user = user; this.user = user;
} }

View File

@ -62,13 +62,13 @@ public class RtSimulationService {
public RtSimulation create(AccountVO accountVO, Long mapId, MapPrdTypeEnum prdTypeEnum) { public RtSimulation create(AccountVO accountVO, Long mapId, MapPrdTypeEnum prdTypeEnum) {
Objects.requireNonNull(mapId); Objects.requireNonNull(mapId);
MapVO mapVO = this.mapService.getMapDetail(mapId); MapVO mapVO = this.mapService.getMapDetail(mapId);
RtSimulationUser creator = new RtSimulationUser(accountVO.getId().toString()); RtSimulationUser creator = new RtSimulationUser(accountVO.getId().toString(), accountVO.getNickname());
RtSimulation rtSimulation = new RtSimulation(SimulationIdGenerator.buildId(), creator, prdTypeEnum); RtSimulation rtSimulation = new RtSimulation(SimulationIdGenerator.buildId(), creator, prdTypeEnum);
this.simulationManager.save(rtSimulation); this.simulationManager.save(rtSimulation);
try { try {
rtSimulation.mapVO = mapVO; rtSimulation.mapVO = mapVO;
this.loadingMap(rtSimulation, mapVO); this.loadingMap(rtSimulation, mapVO);
this.loadRunPlan(rtSimulation, this.queryUserRunPlan(accountVO.getId(), mapId)); this.loadRunPlan(rtSimulation, this.queryUserRunPlan(mapId, accountVO.getId()));
this.initSimulationMember(rtSimulation); this.initSimulationMember(rtSimulation);
this.initCreatorPlayMember(rtSimulation, mapVO); this.initCreatorPlayMember(rtSimulation, mapVO);
} catch (Exception e) { } catch (Exception e) {

View File

@ -4,8 +4,8 @@ import club.joylink.rtss.simulation.SimulationUser;
import club.joylink.rtss.simulation.vo.SimulationUserVO; import club.joylink.rtss.simulation.vo.SimulationUserVO;
public class RtSimulationUser extends SimulationUser { public class RtSimulationUser extends SimulationUser {
public RtSimulationUser(String id) { public RtSimulationUser(String id, String name) {
super(id); super(id, name);
} }
@Override @Override

View File

@ -185,7 +185,7 @@ public class TlTrain extends TlDevice {
// G7(7, 95, 250, 0.41f, 0.29f), // G7(7, 95, 250, 0.41f, 0.29f),
// G8(8, 120, 300, 0.35f, 0.21f), // G8(8, 120, 300, 0.35f, 0.21f),
// G9(9, 150, 360, 0.26f, 0.16f), // G9(9, 150, 360, 0.26f, 0.16f),
G(1, 3, 360, 1.69f, 0.18f) G(1, 3, 350, 1.69f, 0.18f)
; ;
int gear; int gear;

View File

@ -4,6 +4,7 @@ import club.joylink.rtss.simulation.Simulation;
import lombok.Getter; import lombok.Getter;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List;
@Getter @Getter
public class SimulationInfoVO { public class SimulationInfoVO {
@ -18,6 +19,7 @@ public class SimulationInfoVO {
// Integer minute; // Integer minute;
// Integer second; // Integer second;
Integer state; Integer state;
List<SimulationUserVO> userList;
public SimulationInfoVO(Simulation simulation) { public SimulationInfoVO(Simulation simulation) {
this.id = simulation.getId(); this.id = simulation.getId();
@ -34,4 +36,7 @@ public class SimulationInfoVO {
// this.second = systemTime.getSecond(); // this.second = systemTime.getSecond();
} }
public void setUserList(List<SimulationUserVO> userList) {
this.userList = userList;
}
} }

View File

@ -12,6 +12,8 @@ public class SimulationUserVO {
* 仿真用户唯一标识并且是发布订阅消息时的用户唯一标识 * 仿真用户唯一标识并且是发布订阅消息时的用户唯一标识
*/ */
private String id; private String id;
private String name;
private int creator;
/** /**
* 用户仿真消息订阅 * 用户仿真消息订阅
* key-wsSessionId * key-wsSessionId
@ -23,7 +25,18 @@ public class SimulationUserVO {
public SimulationUserVO(SimulationUser user) { public SimulationUserVO(SimulationUser user) {
this.id = user.getId(); this.id = user.getId();
this.name = user.getName();
this.creator = convert(user.isCreator());
this.wsSubscribeMap = user.getSubscribeMap(); this.wsSubscribeMap = user.getSubscribeMap();
this.memberId = user.getMemberId(); this.memberId = user.getMemberId();
} }
public int convert(boolean val) {
if (val) {
return 1;
} else {
return 0;
}
}
} }