Merge branch 'master' of https://git.code.tencent.com/xian-ncc-da/xian-ncc-da-server into master-zy
This commit is contained in:
commit
50129e0e87
@ -1,10 +1,10 @@
|
|||||||
FROM openjdk:17
|
FROM openjdk:17
|
||||||
|
|
||||||
ADD target/xian-ncc-da-0.1.jar app.jar
|
ADD target/xian-ncc-da-0.1.jar xian-ncc-da.jar
|
||||||
|
|
||||||
EXPOSE 9000 19000/tcp
|
EXPOSE 9081
|
||||||
|
|
||||||
ENV TZ=Asia/Shanghai
|
ENV TZ=Asia/Shanghai
|
||||||
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||||
|
|
||||||
CMD java -jar -Dfile.encoding=UTF-8 -Dspring.profiles.active=dev /app.jar
|
CMD java -jar -Dfile.encoding=UTF-8 -Dspring.profiles.active=dev /xian-ncc-da.jar
|
||||||
|
@ -46,112 +46,115 @@ public enum MessageId {
|
|||||||
DEPOT_PLAN(0x0007, () -> new DepotPlanResponse()),
|
DEPOT_PLAN(0x0007, () -> new DepotPlanResponse()),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 列车报点
|
* 2.7.8 列车报点消息
|
||||||
*/
|
*/
|
||||||
TRAIN_RECORD(0x0008, () -> new TrainRecordResponse()),
|
TRAIN_RECORD(0x0008, () -> new TrainRecordResponse()),
|
||||||
/**
|
/**
|
||||||
* 列车信息全体
|
* 2.7.9 列车信息全体消息
|
||||||
*/
|
*/
|
||||||
TRAIN_INDICATION_INIT(0x0009, () -> new TrainIndicationInitResponse()),
|
TRAIN_INDICATION_INIT(0x0009, () -> new TrainIndicationInitResponse()),
|
||||||
/**
|
/**
|
||||||
* 列车信息更新
|
* 2.7.10 列车信息更新消息[增加/更新]
|
||||||
*/
|
*/
|
||||||
TRAIN_INDICATION_UPDATE(0x0010, () -> new TrainIndicationUpdateResponse()),
|
TRAIN_INDICATION_UPDATE(0x0010, () -> new TrainIndicationUpdateResponse()),
|
||||||
/**
|
/**
|
||||||
* 列车信息删除
|
* 2.7.11 列车信息删除消息
|
||||||
*/
|
*/
|
||||||
TRAIN_INDICATION_REMOVE(0x0011, () -> new TrainIndicationRemoveResponse()),
|
TRAIN_INDICATION_REMOVE(0x0011, () -> new TrainIndicationRemoveResponse()),
|
||||||
/**
|
/**
|
||||||
* 统计信息查询
|
* 2.8.1 统计信息查询消息
|
||||||
*/
|
*/
|
||||||
REPORT_ASK(0x0012, null),
|
REPORT_ASK(0x0012, null),
|
||||||
/**
|
/**
|
||||||
* 车组运行里程报告
|
* 2.8.4 车组运行里程报告消息
|
||||||
*/
|
*/
|
||||||
GROUP_RUNNING_REPORT(0x0013, () -> new GroupRunningReportResponse()),
|
GROUP_RUNNING_REPORT(0x0013, () -> new GroupRunningReportResponse()),
|
||||||
/**
|
/**
|
||||||
* 司机驾驶里程报告
|
*2.8.5 司机驾驶里程报告消息
|
||||||
*/
|
*/
|
||||||
DRIVER_DISTANCE_REPORT(0x0014, () -> new DriverDistanceReportResponse()),
|
DRIVER_DISTANCE_REPORT(0x0014, () -> new DriverDistanceReportResponse()),
|
||||||
/**
|
/**
|
||||||
* 调度日志报告
|
* 2.8.6 调度日志报告消息
|
||||||
*/
|
*/
|
||||||
DISPATCHER_REPORT(0x0015, null),
|
DISPATCHER_REPORT(0x0015, ()->new DispatcherReportResponse()),
|
||||||
/**
|
/**
|
||||||
* 存备车报告
|
* 2.8.7 存备车报告消息
|
||||||
*/
|
*/
|
||||||
GROUP_BAK_REPORT(0x0016, null),
|
GROUP_BAK_REPORT(0x0016, ()->new GroupBakReportResponse()),
|
||||||
/**
|
/**
|
||||||
* 列车整备状态报告
|
* 2.8.8 列车整备状态报告消息
|
||||||
*/
|
*/
|
||||||
GROUP_STATUS_REPORT(0x0017, null),
|
GROUP_STATUS_REPORT(0x0017, ()->new GroupStatusReportResponse()),
|
||||||
/**
|
/**
|
||||||
* 事件及告警信息请求
|
* 2.8.9 事件及告警信息请求消息
|
||||||
*/
|
*/
|
||||||
ALARM_ASK(0x0018, () -> new AlarmAckRequest()),
|
ALARM_ASK(0x0018, () -> new AlarmAckRequest()),
|
||||||
/**
|
/**
|
||||||
* 操作命令
|
* 2.8.10 操作命令消息
|
||||||
*/
|
*/
|
||||||
ACTION_REPORT(0x0019, () -> new ActionReportResponse()),
|
ACTION_REPORT(0x0019, () -> new ActionReportResponse()),
|
||||||
/**
|
/**
|
||||||
* 列车信息、系统事件
|
* 2.8.11 列车信息、系统事件消息
|
||||||
*/
|
*/
|
||||||
ALARM_REPORT(0x0020, () -> new AlarmReportResponse()),
|
ALARM_REPORT(0x0020, () -> new AlarmReportResponse()),
|
||||||
/**
|
/**
|
||||||
* 历史运行图申请
|
* 2.8.13 历史运行图申请消息
|
||||||
*/
|
*/
|
||||||
LOAD_HISTORY_TG_DATA(0x0021, () -> new LoadHistoryTGDataRequest()),
|
LOAD_HISTORY_TG_DATA(0x0021, () -> new LoadHistoryTGDataRequest()),
|
||||||
/**
|
/**
|
||||||
* 计划列车运行图消息
|
* 2.8.14 计划列车运行图消息
|
||||||
*/
|
*/
|
||||||
INUSED_SCHEDULE(0x0022, () -> new InusedScheduleResponse()),
|
INUSED_SCHEDULE(0x0022, () -> new InusedScheduleResponse()),
|
||||||
/**
|
/**
|
||||||
* 实际列车运行图消息
|
* 2.8.15 实际列车运行图消息
|
||||||
*/
|
*/
|
||||||
HISTORY_SCHEDULE(0x0023, () -> new HistoryScheduleResponse()),
|
HISTORY_SCHEDULE(0x0023, () -> new HistoryScheduleResponse()),
|
||||||
/**
|
/**
|
||||||
* 断电续传申请
|
* 2.9.3.1 断点续传申请消息
|
||||||
*/
|
*/
|
||||||
Resume_ASK(0x0024, null),
|
Resume_ASK(0x0024, null),
|
||||||
/**
|
/**
|
||||||
* 断点续传开始
|
* 2.9.3.2 断点续传开始消息
|
||||||
*/
|
*/
|
||||||
Resume_Begin_ACK(0x0025, null),
|
Resume_Begin_ACK(0x0025, ()->new ResumeBeginAckResponse()),
|
||||||
/**
|
/**
|
||||||
* 断点续传结束
|
* 2.9.3.4 断点续传结束消息
|
||||||
*/
|
*/
|
||||||
Resume_END_ACK(0x0026, null),
|
Resume_END_ACK(0x0026, ()->new ResumeEndAckResponse()),
|
||||||
/**
|
/**
|
||||||
* 查询无结果消息
|
* 2.8.12 查询无结果消息
|
||||||
*/
|
*/
|
||||||
REPORT_NACK(0x0027, null),
|
REPORT_NACK(0x0027, null),
|
||||||
/**
|
/**
|
||||||
* 查询结果开始消息
|
* 2.8.2 查询结果开始消息
|
||||||
*/
|
*/
|
||||||
REPORT_BEGIN(0x0028, () -> new ReportBeginResponse()),
|
REPORT_BEGIN(0x0028, () -> new ReportBeginResponse()),
|
||||||
/**
|
/**
|
||||||
* 查询结果结束消息
|
* 2.8.3 查询结果结束消息
|
||||||
*/
|
*/
|
||||||
REPORT_END(0x0029, () -> new ReportEndResponse()),
|
REPORT_END(0x0029, () -> new ReportEndResponse()),
|
||||||
/**
|
/**
|
||||||
* 断点续传数据消息
|
* 2.9.3.3 断点续传数据消息
|
||||||
*/
|
*/
|
||||||
Resume_DATA(0x0030, null),
|
Resume_DATA(0x0030, ()->new ResumeDataResponse()),
|
||||||
/**
|
/**
|
||||||
* 实时报警事件消息
|
* 2.7.12 实时报警事件消息
|
||||||
*/
|
*/
|
||||||
MESSAGE_ALARM(0x0031, () -> new MessageAlarmResponse()),
|
MESSAGE_ALARM(0x0031, () -> new MessageAlarmResponse()),
|
||||||
/**
|
/**
|
||||||
* 列车阻塞消息
|
* 2.7.13 列车阻塞消息
|
||||||
*/
|
*/
|
||||||
TRAIN_BLOCK_INFO(0x0032, () -> new TrainBlockInfoResponse()),
|
TRAIN_BLOCK_INFO(0x0032, () -> new TrainBlockInfoResponse()),
|
||||||
/**
|
/**
|
||||||
* 当天计划运行图参数消息
|
* 2.7.14 当天计划运行图参数消息
|
||||||
*/
|
*/
|
||||||
INUSED_SCHEDULE_PARAMETER(0x0033, () -> new InUsedScheduleParameterResponse()),
|
INUSED_SCHEDULE_PARAMETER(0x0033, () -> new InUsedScheduleParameterResponse()),
|
||||||
;
|
;
|
||||||
|
|
||||||
int val;
|
int val;
|
||||||
|
public int idValue(){
|
||||||
|
return this.val;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 消息对象创建接口
|
* 消息对象创建接口
|
||||||
*/
|
*/
|
||||||
@ -167,6 +170,15 @@ public enum MessageId {
|
|||||||
this.omc = omc;
|
this.omc = omc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MessageData create() {
|
||||||
|
return null != this.omc ? this.omc.create() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessageResponse createResponse() {
|
||||||
|
final MessageData messageData = create();
|
||||||
|
if(null==messageData) return null;
|
||||||
|
return messageData instanceof MessageResponse ? (MessageResponse) messageData : null;
|
||||||
|
}
|
||||||
public static MessageId of(int val) {
|
public static MessageId of(int val) {
|
||||||
for (MessageId messageId : MessageId.values()) {
|
for (MessageId messageId : MessageId.values()) {
|
||||||
if (messageId.val == val) {
|
if (messageId.val == val) {
|
||||||
|
@ -9,9 +9,9 @@ import java.util.List;
|
|||||||
|
|
||||||
public class OccMessageDecoder extends ByteToMessageDecoder {
|
public class OccMessageDecoder extends ByteToMessageDecoder {
|
||||||
|
|
||||||
final TcpClientConnection connection;
|
final OccTcpClientConnection connection;
|
||||||
|
|
||||||
public OccMessageDecoder(TcpClientConnection connection) {
|
public OccMessageDecoder(OccTcpClientConnection connection) {
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,9 +9,9 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class OccMessageEncoder extends MessageToByteEncoder<List<MessageData>> {
|
public class OccMessageEncoder extends MessageToByteEncoder<List<MessageData>> {
|
||||||
|
|
||||||
final TcpClientConnection connection;
|
final OccTcpClientConnection connection;
|
||||||
|
|
||||||
public OccMessageEncoder(TcpClientConnection connection) {
|
public OccMessageEncoder(OccTcpClientConnection connection) {
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ public class OccMessageManage implements ApplicationRunner {
|
|||||||
// 读取数据配置,创建客户端
|
// 读取数据配置,创建客户端
|
||||||
this.registerClient(new XianOccMessagingClient(3, "localhost"));
|
this.registerClient(new XianOccMessagingClient(3, "localhost"));
|
||||||
for (XianOccMessagingClient client : this.clientMap.values()) {
|
for (XianOccMessagingClient client : this.clientMap.values()) {
|
||||||
client.connection.connect();
|
client.connect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,14 +7,13 @@ import io.netty.channel.ChannelInitializer;
|
|||||||
import io.netty.channel.EventLoopGroup;
|
import io.netty.channel.EventLoopGroup;
|
||||||
import io.netty.channel.nio.NioEventLoopGroup;
|
import io.netty.channel.nio.NioEventLoopGroup;
|
||||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class TcpClientConnection {
|
public class OccTcpClientConnection {
|
||||||
|
|
||||||
|
|
||||||
XianOccMessagingClient client;
|
XianOccMessagingClient client;
|
||||||
@ -24,11 +23,14 @@ public class TcpClientConnection {
|
|||||||
|
|
||||||
final EventLoopGroup group;
|
final EventLoopGroup group;
|
||||||
final Bootstrap bootstrap;
|
final Bootstrap bootstrap;
|
||||||
volatile boolean connected;
|
|
||||||
/**
|
/**
|
||||||
* 连接管道
|
* 连接状态
|
||||||
*/
|
*/
|
||||||
|
volatile boolean connected;
|
||||||
Channel channel;
|
Channel channel;
|
||||||
|
/**
|
||||||
|
* 心跳超时重连处理器
|
||||||
|
*/
|
||||||
HeartBeatTimeoutHandler timeoutHandler;
|
HeartBeatTimeoutHandler timeoutHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,13 +38,13 @@ public class TcpClientConnection {
|
|||||||
*/
|
*/
|
||||||
volatile long lastReceiveMessageTime;
|
volatile long lastReceiveMessageTime;
|
||||||
|
|
||||||
public TcpClientConnection(XianOccMessagingClient client, String host, int port) {
|
public OccTcpClientConnection(XianOccMessagingClient client, String host, int port) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.host = host;
|
this.host = host;
|
||||||
this.port = port;
|
this.port = port;
|
||||||
this.group = new NioEventLoopGroup();
|
this.group = new NioEventLoopGroup(1);
|
||||||
this.bootstrap = new Bootstrap();
|
this.bootstrap = new Bootstrap();
|
||||||
TcpClientConnection self = this;
|
OccTcpClientConnection self = this;
|
||||||
bootstrap.group(group)
|
bootstrap.group(group)
|
||||||
.channel(NioSocketChannel.class)
|
.channel(NioSocketChannel.class)
|
||||||
.handler(new ChannelInitializer<>() {
|
.handler(new ChannelInitializer<>() {
|
||||||
@ -65,30 +67,28 @@ public class TcpClientConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void connect() {
|
public synchronized void connect() {
|
||||||
try {
|
|
||||||
ChannelFuture channelFuture = bootstrap.connect(this.host, this.port);
|
ChannelFuture channelFuture = bootstrap.connect(this.host, this.port);
|
||||||
channelFuture.addListener(future1 -> {
|
channelFuture.addListener(future1 -> {
|
||||||
if (future1.isSuccess()) {
|
if (future1.isSuccess()) {
|
||||||
log.info("连接到OCC服务: host={}, port={}", this.host, this.port);
|
log.info("连接到OCC服务: {}", this.hostPortInfo());
|
||||||
this.connected = true;
|
this.lastReceiveMessageTime = System.currentTimeMillis();
|
||||||
this.channel = channelFuture.channel();
|
this.channel = channelFuture.channel();
|
||||||
// 启动心跳超时监测
|
this.connected = true;
|
||||||
this.timeoutHandler.start();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
channelFuture.channel().closeFuture().addListener(listener -> {
|
channelFuture.channel().closeFuture().addListener(listener -> {
|
||||||
log.info("与服务断连,尝试重连");
|
if (listener.isSuccess()) {
|
||||||
this.timeoutHandler.stop();
|
log.info("与服务断连,尝试重连: {}", this.hostPortInfo());
|
||||||
this.connected = false;
|
this.connected = false;
|
||||||
this.channel = null;
|
this.channel = null;
|
||||||
|
|
||||||
Thread.sleep(3000);
|
Thread.sleep(3000);
|
||||||
connect();
|
connect();
|
||||||
});
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("与OCC服务连接异常,尝试重连", e);
|
|
||||||
connect();
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
String hostPortInfo() {
|
||||||
|
return String.format("host=%s, port=%s", this.host, this.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
static class HeartBeatTimeoutHandler {
|
static class HeartBeatTimeoutHandler {
|
||||||
@ -99,34 +99,22 @@ public class TcpClientConnection {
|
|||||||
final int HeartBeatTimeout = 15 * 1000;
|
final int HeartBeatTimeout = 15 * 1000;
|
||||||
static final int Period = 2;
|
static final int Period = 2;
|
||||||
|
|
||||||
TcpClientConnection connection;
|
OccTcpClientConnection connection;
|
||||||
boolean running;
|
|
||||||
static final ScheduledExecutorService Executor = Executors.newSingleThreadScheduledExecutor();
|
static final ScheduledExecutorService Executor = Executors.newSingleThreadScheduledExecutor();
|
||||||
|
|
||||||
public HeartBeatTimeoutHandler(TcpClientConnection connection) {
|
public HeartBeatTimeoutHandler(OccTcpClientConnection connection) {
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
Executor.scheduleAtFixedRate(() -> {
|
Executor.scheduleAtFixedRate(() -> {
|
||||||
if (running) {
|
if (connection.connected) {
|
||||||
long ctm = System.currentTimeMillis();
|
long ctm = System.currentTimeMillis();
|
||||||
if (connection.lastReceiveMessageTime + HeartBeatTimeout < ctm) {
|
if (connection.lastReceiveMessageTime + HeartBeatTimeout < ctm) {
|
||||||
log.info("超时未收到OCC消息,尝试重连: host={}, port={}", connection.host,
|
log.info("超时未收到OCC消息,尝试断开重连");
|
||||||
connection.port);
|
|
||||||
connection.reconnect();
|
connection.reconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, Period, Period, TimeUnit.SECONDS);
|
}, Period, Period, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void start() {
|
|
||||||
// log.info("心跳超时监控启动");
|
|
||||||
this.running = true;
|
|
||||||
connection.lastReceiveMessageTime = System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
|
|
||||||
void stop() {
|
|
||||||
// log.info("心跳超时监控stop");
|
|
||||||
this.running = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -13,51 +13,34 @@ public class XianOccMessagingClient {
|
|||||||
*/
|
*/
|
||||||
final int lineId;
|
final int lineId;
|
||||||
final String host;
|
final String host;
|
||||||
/**
|
|
||||||
* 实时端口号
|
|
||||||
*/
|
|
||||||
final int realTimePort;
|
|
||||||
/**
|
|
||||||
* 非实时端口号
|
|
||||||
*/
|
|
||||||
final int nonRealTimePort;
|
|
||||||
/**
|
|
||||||
* 版本号
|
|
||||||
*/
|
|
||||||
final int Version = 0x01;
|
|
||||||
/**
|
|
||||||
* 心跳发送间隔
|
|
||||||
*/
|
|
||||||
final int heartbeatInterval = 10;
|
|
||||||
/**
|
|
||||||
* 心跳超时
|
|
||||||
*/
|
|
||||||
final int heartbeatTimeout = 15;
|
|
||||||
|
|
||||||
final TcpClientConnection connection;
|
/**
|
||||||
|
* 实时消息的连接
|
||||||
|
*/
|
||||||
|
private final OccTcpClientConnection rtConnection;
|
||||||
|
/**
|
||||||
|
* 非实时消息的连接
|
||||||
|
*/
|
||||||
|
private final OccTcpClientConnection nrtConnection;
|
||||||
|
|
||||||
|
|
||||||
public XianOccMessagingClient(int lineId, String host) {
|
public XianOccMessagingClient(int lineId, String host) {
|
||||||
this.host = host;
|
this.host = host;
|
||||||
this.lineId = lineId;
|
this.lineId = lineId;
|
||||||
this.realTimePort = realTimePortBase + lineId;
|
final int realTimePort = realTimePortBase + lineId;
|
||||||
this.nonRealTimePort = nonRealTimePortBase + lineId;
|
final int nonRealTimePort = nonRealTimePortBase + lineId;
|
||||||
// 创建实时消息连接
|
// 创建实时和非实时消息连接
|
||||||
this.connection = new TcpClientConnection(this, host, this.realTimePort);
|
this.rtConnection = new OccTcpClientConnection(this, host, realTimePort);
|
||||||
|
this.nrtConnection = new OccTcpClientConnection(this, host, nonRealTimePort);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 连接实时消息服务
|
* 连接OCC服务
|
||||||
*/
|
*/
|
||||||
public void rtMessageConnect() {
|
public void connect() {
|
||||||
|
// 实时消息连接
|
||||||
|
this.rtConnection.connect();
|
||||||
|
// 非实时消息连接
|
||||||
|
this.nrtConnection.connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 连接非实时消息服务
|
|
||||||
*/
|
|
||||||
public void nrtMessageConnect() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -24,4 +24,25 @@ public class DateTimeUtil {
|
|||||||
buf.writeByte(from.getMinute());
|
buf.writeByte(from.getMinute());
|
||||||
buf.writeByte(from.getSecond());
|
buf.writeByte(from.getSecond());
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 例如,传送2001年9月21日15时29分30秒,则年、月、日、时、分、秒各单元的值分别为:20、01、9、21、15、29、30
|
||||||
|
*/
|
||||||
|
public static byte[]convert(final LocalDateTime from){
|
||||||
|
final byte[] to = new byte[7];
|
||||||
|
convert(from,to);
|
||||||
|
return to;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 例如,传送2001年9月21日15时29分30秒,则01年、2月、3日、4时、5分、6秒各单元的值分别为:20、01、9、21、15、29、30
|
||||||
|
*/
|
||||||
|
public static LocalDateTime convert(final byte[]from){
|
||||||
|
if (null == from || from.length != 7) throw new RuntimeException("数组from的长度须为7");
|
||||||
|
final int year = Integer.valueOf(String.format("%s%s",String.format("%d",from[0]),String.format("%02d",from[1])));
|
||||||
|
final int month = from[2];
|
||||||
|
final int day = from[3];
|
||||||
|
final int hour = from[4];
|
||||||
|
final int minute = from[5];
|
||||||
|
final int second = from[6];
|
||||||
|
return LocalDateTime.of(year,month,day,hour,minute,second);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,75 @@
|
|||||||
|
package club.joylink.xiannccda.ats.message.line3;
|
||||||
|
|
||||||
|
import club.joylink.xiannccda.ats.message.MessageResponse;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2.8.6 调度日志报告消息
|
||||||
|
*/
|
||||||
|
public class DispatcherReportResponse extends MessageResponse {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 线路号(2)
|
||||||
|
*/
|
||||||
|
private Short lineId;
|
||||||
|
/**
|
||||||
|
* 查询标识号(2)<br>
|
||||||
|
* 同一时间多个查询的report_id不允许重复,答复消息中的report_id值跟查询消息中的相同
|
||||||
|
*/
|
||||||
|
private Short reportId;
|
||||||
|
/**
|
||||||
|
* 消息总数(2)
|
||||||
|
*/
|
||||||
|
private Short totalMessage;
|
||||||
|
/**
|
||||||
|
* 本消息的顺序号(2)
|
||||||
|
*/
|
||||||
|
private Short messageSequence;
|
||||||
|
/**
|
||||||
|
* 记录条数(2)
|
||||||
|
*/
|
||||||
|
private Short count;
|
||||||
|
/**
|
||||||
|
* 调度日志报告列表
|
||||||
|
*/
|
||||||
|
private List<LogCell> logs;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decode2(ByteBuf buf) throws Exception {
|
||||||
|
this.lineId=buf.readShort();
|
||||||
|
this.reportId=buf.readShort();
|
||||||
|
this.totalMessage=buf.readShort();
|
||||||
|
this.messageSequence=buf.readShort();
|
||||||
|
this.count=buf.readShort();
|
||||||
|
this.logs=new ArrayList<>(this.count);
|
||||||
|
for(int i=0;i<this.count;i++){
|
||||||
|
this.logs.add(new LogCell().decode(buf));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class LogCell {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日期(7)
|
||||||
|
*/
|
||||||
|
private byte[] reportTime = new byte[7];
|
||||||
|
/**
|
||||||
|
* 调度员(32)
|
||||||
|
*/
|
||||||
|
private byte[] userName = new byte[32];
|
||||||
|
/**
|
||||||
|
* 记录内容(256)
|
||||||
|
*/
|
||||||
|
private byte[] logItem = new byte[256];
|
||||||
|
|
||||||
|
public LogCell decode(final ByteBuf buf) {
|
||||||
|
buf.readBytes(this.reportTime);
|
||||||
|
buf.readBytes(this.userName);
|
||||||
|
buf.readBytes(this.logItem);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,85 @@
|
|||||||
|
package club.joylink.xiannccda.ats.message.line3;
|
||||||
|
|
||||||
|
import club.joylink.xiannccda.ats.message.MessageResponse;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2.8.7 存备车报告消息
|
||||||
|
*/
|
||||||
|
public class GroupBakReportResponse extends MessageResponse {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 线路号(2)
|
||||||
|
*/
|
||||||
|
private Short lineId;
|
||||||
|
/**
|
||||||
|
* 查询标识号(2)<br>
|
||||||
|
* 同一时间多个查询的report_id不允许重复,答复消息中的report_id值跟查询消息中的相同
|
||||||
|
*/
|
||||||
|
private Short reportId;
|
||||||
|
/**
|
||||||
|
* 消息总数(2)
|
||||||
|
*/
|
||||||
|
private Short totalMessage;
|
||||||
|
/**
|
||||||
|
* 本消息的顺序号(2)
|
||||||
|
*/
|
||||||
|
private Short messageSequence;
|
||||||
|
/**
|
||||||
|
* 记录条数(2)
|
||||||
|
*/
|
||||||
|
private Short count;
|
||||||
|
/**
|
||||||
|
* 存备车报告列表
|
||||||
|
*/
|
||||||
|
private List<GroupBakCell> groups;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decode2(ByteBuf buf) throws Exception {
|
||||||
|
this.lineId=buf.readShort();
|
||||||
|
this.reportId=buf.readShort();
|
||||||
|
this.totalMessage=buf.readShort();
|
||||||
|
this.messageSequence=buf.readShort();
|
||||||
|
this.count=buf.readShort();
|
||||||
|
this.groups=new ArrayList<>(this.count);
|
||||||
|
for(int i=0;i<this.count;i++){
|
||||||
|
this.groups.add(new GroupBakCell().decode(buf));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static class GroupBakCell{
|
||||||
|
/**
|
||||||
|
* 车组号(9)
|
||||||
|
*/
|
||||||
|
private byte[] groupId = new byte[9];
|
||||||
|
/**
|
||||||
|
* 存备车状态(1)<br>
|
||||||
|
* 0x01:上线运营<br>
|
||||||
|
* 0x02:备车<br>
|
||||||
|
* 0x03:维修 <br>
|
||||||
|
*/
|
||||||
|
private byte status;
|
||||||
|
/**
|
||||||
|
* 所处位置(1)<br>
|
||||||
|
* 0x01:车辆段1<br>
|
||||||
|
* 0x02:停车场1<br>
|
||||||
|
* 0x04:车辆段2<br>
|
||||||
|
* 0x08:停车场2<br>
|
||||||
|
*/
|
||||||
|
private byte depot;
|
||||||
|
/**
|
||||||
|
* 所在轨道名称(20)
|
||||||
|
*/
|
||||||
|
private byte[] trackName = new byte[20];
|
||||||
|
|
||||||
|
public GroupBakCell decode(final ByteBuf buf){
|
||||||
|
buf.readBytes(this.groupId);
|
||||||
|
this.status=buf.readByte();
|
||||||
|
this.depot=buf.readByte();
|
||||||
|
buf.readBytes(this.trackName);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
package club.joylink.xiannccda.ats.message.line3;
|
||||||
|
|
||||||
|
import club.joylink.xiannccda.ats.message.MessageResponse;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2.8.8 列车整备状态报告消息
|
||||||
|
*/
|
||||||
|
public class GroupStatusReportResponse extends MessageResponse {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 线路号(2)
|
||||||
|
*/
|
||||||
|
private Short lineId;
|
||||||
|
/**
|
||||||
|
* 查询标识号(2)<br>
|
||||||
|
* 同一时间多个查询的report_id不允许重复,答复消息中的report_id值跟查询消息中的相同
|
||||||
|
*/
|
||||||
|
private Short reportId;
|
||||||
|
/**
|
||||||
|
* 消息总数(2)
|
||||||
|
*/
|
||||||
|
private Short totalMessage;
|
||||||
|
/**
|
||||||
|
* 本消息的顺序号(2)
|
||||||
|
*/
|
||||||
|
private Short messageSequence;
|
||||||
|
/**
|
||||||
|
* 记录条数(2)
|
||||||
|
*/
|
||||||
|
private Short count;
|
||||||
|
/**
|
||||||
|
* 列车整备状态列表
|
||||||
|
*/
|
||||||
|
private List<GroupStatusCell> groups;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decode2(ByteBuf buf) throws Exception {
|
||||||
|
this.lineId = buf.readShort();
|
||||||
|
this.reportId = buf.readShort();
|
||||||
|
this.totalMessage = buf.readShort();
|
||||||
|
this.messageSequence = buf.readShort();
|
||||||
|
this.count = buf.readShort();
|
||||||
|
this.groups = new ArrayList<>(this.count);
|
||||||
|
for (int i = 0; i < this.count; i++) {
|
||||||
|
this.groups.add(new GroupStatusCell().decode(buf));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class GroupStatusCell {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 车组号(9)
|
||||||
|
*/
|
||||||
|
private byte[] groupId = new byte[9];
|
||||||
|
/**
|
||||||
|
* 列车位置(1)<br>
|
||||||
|
* 0x01:车辆段/停车场<br>
|
||||||
|
* 0x02: 正线<br>
|
||||||
|
*/
|
||||||
|
private byte depot;
|
||||||
|
/**
|
||||||
|
* 整备状态(42)
|
||||||
|
*/
|
||||||
|
private byte[] status = new byte[42];
|
||||||
|
|
||||||
|
public GroupStatusCell decode(final ByteBuf buf) {
|
||||||
|
buf.readBytes(this.groupId);
|
||||||
|
this.depot = buf.readByte();
|
||||||
|
buf.readBytes(this.status);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package club.joylink.xiannccda.ats.message.line3;
|
||||||
|
|
||||||
|
import club.joylink.xiannccda.ats.message.MessageId;
|
||||||
|
import club.joylink.xiannccda.ats.message.MessageRequest;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2.9.3.1 断点续传申请消息<br>
|
||||||
|
* 时间范围说明:<br>
|
||||||
|
* 申请消息的时间范围(结束时间与开始时间之差)不超过1小时。<br>
|
||||||
|
*/
|
||||||
|
public class ResumeAskRequest extends MessageRequest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 线路号(2)
|
||||||
|
*/
|
||||||
|
private Short lineId;
|
||||||
|
/**
|
||||||
|
* 开始时间(7)
|
||||||
|
*/
|
||||||
|
private byte[] beginTime;
|
||||||
|
/**
|
||||||
|
* 结束时间(7)
|
||||||
|
*/
|
||||||
|
private byte[] endTime;
|
||||||
|
|
||||||
|
public ResumeAskRequest(Short lineId, LocalDateTime begin, LocalDateTime end) {
|
||||||
|
super(MessageId.Resume_ASK, 2 + 7 + 7);
|
||||||
|
this.lineId = lineId;
|
||||||
|
this.beginTime = new byte[7];
|
||||||
|
Arrays.fill(this.beginTime, (byte) 0);
|
||||||
|
DateTimeUtil.convert(begin, this.beginTime);
|
||||||
|
this.endTime = new byte[7];
|
||||||
|
Arrays.fill(this.endTime, (byte) 0);
|
||||||
|
DateTimeUtil.convert(end, this.endTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode2(ByteBuf buf) {
|
||||||
|
buf.writeShort(this.lineId);
|
||||||
|
buf.writeBytes(this.beginTime);
|
||||||
|
buf.writeBytes(this.endTime);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package club.joylink.xiannccda.ats.message.line3;
|
||||||
|
|
||||||
|
import club.joylink.xiannccda.ats.message.MessageResponse;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2.9.3.2 断点续传开始消息
|
||||||
|
*/
|
||||||
|
public class ResumeBeginAckResponse extends MessageResponse {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 线路号(2)
|
||||||
|
*/
|
||||||
|
private Short lineId;
|
||||||
|
/**
|
||||||
|
* 开始时间(7)
|
||||||
|
*/
|
||||||
|
private byte[] beginTime = new byte[7];
|
||||||
|
/**
|
||||||
|
* 结束时间(7)
|
||||||
|
*/
|
||||||
|
private byte[] endTime = new byte[7];
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decode2(ByteBuf buf) throws Exception {
|
||||||
|
this.lineId = buf.readShort();
|
||||||
|
buf.readBytes(this.beginTime);
|
||||||
|
buf.readBytes(this.endTime);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
package club.joylink.xiannccda.ats.message.line3;
|
||||||
|
|
||||||
|
import club.joylink.xiannccda.ats.message.MessageId;
|
||||||
|
import club.joylink.xiannccda.ats.message.MessageResponse;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2.9.3.3 断点续传数据消息
|
||||||
|
*/
|
||||||
|
public class ResumeDataResponse extends MessageResponse {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 线路号(2)
|
||||||
|
*/
|
||||||
|
private Short lineId;
|
||||||
|
/**
|
||||||
|
* 消息总数(2)
|
||||||
|
*/
|
||||||
|
private Short totalMessage;
|
||||||
|
/**
|
||||||
|
* 本消息的顺序号(2)
|
||||||
|
*/
|
||||||
|
private Short messageSequence;
|
||||||
|
/**
|
||||||
|
* 消息message_data的数量(2)
|
||||||
|
*/
|
||||||
|
private Short msgCnt;
|
||||||
|
/**
|
||||||
|
* 补传的消息(全部为响应类消息)。消息格式、内容和本接口协议定义的消息格式一致,时间戳保持与实时发送时的一致
|
||||||
|
*/
|
||||||
|
private List<MessageResponse> messageData;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decode2(ByteBuf buf) throws Exception {
|
||||||
|
this.lineId = buf.readShort();
|
||||||
|
this.totalMessage = buf.readShort();
|
||||||
|
this.messageSequence = buf.readShort();
|
||||||
|
this.msgCnt = buf.readShort();
|
||||||
|
this.messageData = new ArrayList<>(this.msgCnt);
|
||||||
|
//
|
||||||
|
for (int i = 0; i < this.msgCnt; i++) {
|
||||||
|
final int _readIndex = buf.readerIndex();
|
||||||
|
buf.skipBytes(8);
|
||||||
|
final MessageId messageId = MessageId.of(buf.readShort());
|
||||||
|
buf.readerIndex(_readIndex);
|
||||||
|
final MessageResponse messageResponse = messageId.createResponse();
|
||||||
|
messageResponse.decode(buf);
|
||||||
|
this.messageData.add(messageResponse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package club.joylink.xiannccda.ats.message.line3;
|
||||||
|
|
||||||
|
import club.joylink.xiannccda.ats.message.MessageResponse;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2.9.3.4 断点续传结束消息
|
||||||
|
*/
|
||||||
|
public class ResumeEndAckResponse extends MessageResponse {
|
||||||
|
/**
|
||||||
|
* 线路号(2)
|
||||||
|
*/
|
||||||
|
private Short lineId;
|
||||||
|
/**
|
||||||
|
* 开始时间(7)
|
||||||
|
*/
|
||||||
|
private byte[] beginTime = new byte[7];
|
||||||
|
/**
|
||||||
|
* 结束时间(7)
|
||||||
|
*/
|
||||||
|
private byte[] endTime = new byte[7];
|
||||||
|
@Override
|
||||||
|
public void decode2(ByteBuf buf) throws Exception {
|
||||||
|
this.lineId = buf.readShort();
|
||||||
|
buf.readBytes(this.beginTime);
|
||||||
|
buf.readBytes(this.endTime);
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,8 @@ import club.joylink.xiannccda.exception.BusinessException;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ProblemDetail;
|
import org.springframework.http.ProblemDetail;
|
||||||
|
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||||
|
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
|
|
||||||
@ -20,6 +22,15 @@ public class ResponseExceptionHandler {
|
|||||||
return problemDetail;
|
return problemDetail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler({HttpMessageNotReadableException.class, MethodArgumentNotValidException.class})
|
||||||
|
public ProblemDetail messageReadExceptionHandler(Exception e) {
|
||||||
|
log.error("客户端参数异常", e);
|
||||||
|
ProblemDetail problemDetail = ProblemDetail.forStatus(HttpStatus.PAYMENT_REQUIRED);
|
||||||
|
problemDetail.setProperty("code", HttpStatus.PAYMENT_REQUIRED);
|
||||||
|
problemDetail.setTitle(e.getMessage());
|
||||||
|
return problemDetail;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统未处理异常捕获
|
* 系统未处理异常捕获
|
||||||
*
|
*
|
||||||
|
@ -5,14 +5,14 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* 前端控制器
|
* 线路信息 前端控制器
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author walker-sheng
|
* @author walker-sheng
|
||||||
* @since 2023-06-06
|
* @since 2023-06-06
|
||||||
*/
|
*/
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/lineInfo")
|
@RequestMapping("/api/lineInfo")
|
||||||
public class LineInfoController {
|
public class LineInfoController {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
package club.joylink.xiannccda.controller;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 发布图形界面 前端控制器
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author walker-sheng
|
||||||
|
* @since 2023-06-08
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/publishedGi")
|
||||||
|
public class PublishedGiController {
|
||||||
|
|
||||||
|
}
|
@ -21,7 +21,7 @@ import lombok.experimental.Accessors;
|
|||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
@Schema(name = "Drafting", description = "$!{table.comment}")
|
@Schema(name = "Drafting", description = "图形界面草稿数据")
|
||||||
public class Drafting {
|
public class Drafting {
|
||||||
|
|
||||||
@Schema(description = "id")
|
@Schema(description = "id")
|
||||||
@ -32,6 +32,10 @@ public class Drafting {
|
|||||||
@NotBlank(message = "草稿图名称不能为空", groups = {Creation.class, SaveAs.class})
|
@NotBlank(message = "草稿图名称不能为空", groups = {Creation.class, SaveAs.class})
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "草稿图类型", example = "Line/LineNetwork")
|
||||||
|
@NotBlank(message = "草稿图类型不能为空", groups = {Creation.class})
|
||||||
|
private String type;
|
||||||
|
|
||||||
@Schema(description = "绘图数据")
|
@Schema(description = "绘图数据")
|
||||||
@NotNull(message = "数据不能为空", groups = {SaveData.class, SaveAs.class})
|
@NotNull(message = "数据不能为空", groups = {SaveData.class, SaveAs.class})
|
||||||
private byte[] proto;
|
private byte[] proto;
|
||||||
|
@ -21,7 +21,7 @@ import lombok.experimental.Accessors;
|
|||||||
@Setter
|
@Setter
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
@TableName("line_info")
|
@TableName("line_info")
|
||||||
@Schema(name = "LineInfo", description = "$!{table.comment}")
|
@Schema(name = "LineInfo", description = "线路信息数据")
|
||||||
public class LineInfo {
|
public class LineInfo {
|
||||||
|
|
||||||
@Schema(description = "id")
|
@Schema(description = "id")
|
||||||
|
59
src/main/java/club/joylink/xiannccda/entity/PublishedGi.java
Normal file
59
src/main/java/club/joylink/xiannccda/entity/PublishedGi.java
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
package club.joylink.xiannccda.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
*
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author walker-sheng
|
||||||
|
* @since 2023-06-08
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@TableName("published_gi")
|
||||||
|
@Schema(name = "PublishedGi", description = "发布的图形界面数据")
|
||||||
|
public class PublishedGi {
|
||||||
|
|
||||||
|
@Schema(description = "id")
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
@Schema(description = "发布图形界面名称")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "图形界面类型")
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
@Schema(description = "关联的线路号(line_info表中line_id字段)")
|
||||||
|
private Integer lineId;
|
||||||
|
|
||||||
|
@Schema(description = "图形界面数据")
|
||||||
|
private byte[] proto;
|
||||||
|
|
||||||
|
@Schema(description = "发布用户id")
|
||||||
|
private Integer userId;
|
||||||
|
|
||||||
|
@Schema(description = "发布时间")
|
||||||
|
private LocalDateTime publishAt;
|
||||||
|
|
||||||
|
public static final String ID = "id";
|
||||||
|
|
||||||
|
public static final String NAME = "name";
|
||||||
|
|
||||||
|
public static final String TYPE = "type";
|
||||||
|
|
||||||
|
public static final String LINE_ID = "line_id";
|
||||||
|
|
||||||
|
public static final String PROTO = "proto";
|
||||||
|
|
||||||
|
public static final String USER_ID = "user_id";
|
||||||
|
|
||||||
|
public static final String PUBLISH_AT = "publish_at";
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package club.joylink.xiannccda.mapper;
|
||||||
|
|
||||||
|
import club.joylink.xiannccda.entity.PublishedGi;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Mapper 接口
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author walker-sheng
|
||||||
|
* @since 2023-06-08
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface PublishedGiMapper extends BaseMapper<PublishedGi> {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="club.joylink.xiannccda.mapper.PublishedGiMapper">
|
||||||
|
|
||||||
|
<!-- 通用查询映射结果 -->
|
||||||
|
<resultMap id="BaseResultMap" type="club.joylink.xiannccda.entity.PublishedGi">
|
||||||
|
<id column="id" property="id" />
|
||||||
|
<result column="name" property="name" />
|
||||||
|
<result column="type" property="type" />
|
||||||
|
<result column="line_id" property="lineId" />
|
||||||
|
<result column="proto" property="proto" />
|
||||||
|
<result column="user_id" property="userId" />
|
||||||
|
<result column="publish_at" property="publishAt" />
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<!-- 通用查询结果列 -->
|
||||||
|
<sql id="Base_Column_List">
|
||||||
|
id, name, type, line_id, proto, user_id, publish_at
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
</mapper>
|
@ -0,0 +1,16 @@
|
|||||||
|
package club.joylink.xiannccda.repository;
|
||||||
|
|
||||||
|
import club.joylink.xiannccda.entity.PublishedGi;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 服务类
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author walker-sheng
|
||||||
|
* @since 2023-06-08
|
||||||
|
*/
|
||||||
|
public interface IPublishedGiRepository extends IService<PublishedGi> {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package club.joylink.xiannccda.repository.impl;
|
||||||
|
|
||||||
|
import club.joylink.xiannccda.entity.PublishedGi;
|
||||||
|
import club.joylink.xiannccda.mapper.PublishedGiMapper;
|
||||||
|
import club.joylink.xiannccda.repository.IPublishedGiRepository;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 服务实现类
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author walker-sheng
|
||||||
|
* @since 2023-06-08
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class PublishedGiRepository extends ServiceImpl<PublishedGiMapper, PublishedGi> implements IPublishedGiRepository {
|
||||||
|
|
||||||
|
}
|
@ -8,4 +8,5 @@ spring:
|
|||||||
logging:
|
logging:
|
||||||
level:
|
level:
|
||||||
root: "info"
|
root: "info"
|
||||||
|
file:
|
||||||
|
path: /usr/local/joylink/logs/xianncc
|
||||||
|
@ -14,13 +14,12 @@ import io.netty.handler.logging.LoggingHandler;
|
|||||||
public class OccServer {
|
public class OccServer {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
final int PORT = 2603;
|
final int RtPort = 2603;
|
||||||
|
final int NrtPort = 2703;
|
||||||
// Configure the server.
|
// Configure the server.
|
||||||
//创建两个EventLoopGroup对象
|
//创建两个EventLoopGroup对象
|
||||||
EventLoopGroup bossGroup = new NioEventLoopGroup(1);//创建boos线程组,用于服务端接受客户端的连接
|
EventLoopGroup bossGroup = new NioEventLoopGroup(1);//创建boos线程组,用于服务端接受客户端的连接
|
||||||
EventLoopGroup workerGroup = new NioEventLoopGroup();//创建worker线程组,用于进行SocketChannel的数据读写,处理业务逻辑
|
EventLoopGroup workerGroup = new NioEventLoopGroup();//创建worker线程组,用于进行SocketChannel的数据读写,处理业务逻辑
|
||||||
//创建Handler
|
|
||||||
try {
|
|
||||||
//创建ServerBootstrap对象
|
//创建ServerBootstrap对象
|
||||||
ServerBootstrap b = new ServerBootstrap();
|
ServerBootstrap b = new ServerBootstrap();
|
||||||
b.group(bossGroup, workerGroup)//设置EventLoopGroup
|
b.group(bossGroup, workerGroup)//设置EventLoopGroup
|
||||||
@ -34,20 +33,30 @@ public class OccServer {
|
|||||||
p.addLast(new OccHandler());
|
p.addLast(new OccHandler());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
//创建Handler
|
||||||
|
try {
|
||||||
// Start the server.
|
// Start the server.
|
||||||
//绑定端口,并同步等待成功,即启动服务端
|
//绑定端口,并同步等待成功,即启动服务端
|
||||||
ChannelFuture f = b.bind(PORT).addListener(listener -> {
|
ChannelFuture f1 = b.bind(RtPort).addListener(listener -> {
|
||||||
if (listener.isSuccess()) {
|
if (listener.isSuccess()) {
|
||||||
System.out.println("OCC测试服务启动...");
|
System.out.println("OCC测试实时服务启动...");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//绑定端口,并同步等待成功,即启动服务端
|
||||||
|
ChannelFuture f2 = b.bind(NrtPort).addListener(listener -> {
|
||||||
|
if (listener.isSuccess()) {
|
||||||
|
System.out.println("OCC测试非实时服务启动...");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Wait until the server socket is closed.
|
// Wait until the server socket is closed.
|
||||||
//监听服务端关闭,并阻塞等待
|
//监听服务端关闭,并阻塞等待
|
||||||
//这里并不是关闭服务器,而是“监听”服务端关闭
|
//这里并不是关闭服务器,而是“监听”服务端关闭
|
||||||
f.channel().closeFuture().addListener(listener -> {
|
f1.channel().closeFuture().addListener(listener -> {
|
||||||
System.out.println("OCC测试服务关闭");
|
System.out.println("OCC测试实时服务关闭");
|
||||||
|
});
|
||||||
|
f2.channel().closeFuture().addListener(listener -> {
|
||||||
|
System.out.println("OCC测试非实时服务关闭");
|
||||||
}).sync();
|
}).sync();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.err.println("OCC测试服务异常");
|
System.err.println("OCC测试服务异常");
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
package club.joylink.xiannccda.protocal.x;
|
||||||
|
|
||||||
|
import club.joylink.xiannccda.ats.message.MessageId;
|
||||||
|
import club.joylink.xiannccda.ats.message.line3.DateTimeUtil;
|
||||||
|
import club.joylink.xiannccda.ats.message.line3.DispatcherReportResponse;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.ByteBufAllocator;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import io.netty.buffer.UnpooledByteBufAllocator;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class TestDispatcherReportResponse {
|
||||||
|
public static void main(String[]args){
|
||||||
|
final DispatcherReportResponse response = new DispatcherReportResponse();
|
||||||
|
final ByteBufAllocator allocator = UnpooledByteBufAllocator.DEFAULT;
|
||||||
|
final ByteBuf body = allocator.buffer(1024);
|
||||||
|
body.writeInt((int) (System.currentTimeMillis() / 1000));
|
||||||
|
body.writeShort(0xff);
|
||||||
|
body.writeShort(MessageId.DISPATCHER_REPORT.idValue());
|
||||||
|
body.writeShort(3);
|
||||||
|
body.writeShort(110);
|
||||||
|
body.writeShort(2);
|
||||||
|
body.writeShort(1);
|
||||||
|
body.writeShort(2);//Count
|
||||||
|
body.readBytes(DateTimeUtil.convert(LocalDateTime.now()));
|
||||||
|
//
|
||||||
|
final byte[]userName = new byte[32];
|
||||||
|
Arrays.fill(userName, (byte) '\0');
|
||||||
|
final ByteBuf userNameBuf = Unpooled.wrappedBuffer(userName);
|
||||||
|
userNameBuf.readBytes("调度员1".getBytes(StandardCharsets.UTF_8));
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1 +1 @@
|
|||||||
Subproject commit 86de0cff9ee560f0c7e670184d5baccfdb28ee44
|
Subproject commit 2e001eddeeeaea3aa9c607df72d2196572a717da
|
Loading…
Reference in New Issue
Block a user