130 lines
3.5 KiB
Go
130 lines
3.5 KiB
Go
package semi_physical_train
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
|
|
"joylink.club/bj-rtsts-server/config"
|
|
"joylink.club/bj-rtsts-server/third_party/message"
|
|
"joylink.club/bj-rtsts-server/third_party/tpapi"
|
|
"joylink.club/bj-rtsts-server/third_party/udp"
|
|
)
|
|
|
|
// 半实物仿真列车通信接口
|
|
type SemiPhysicalTrain interface {
|
|
tpapi.ThirdPartyApiService
|
|
// 启动半实物仿真消息处理
|
|
Start(manager SemiPhysicalMessageManager)
|
|
// 停止半实物仿真消息处理
|
|
Stop()
|
|
// 发送列车控制消息
|
|
SendTrainControlMessage(info *message.DynamicsTrainInfo)
|
|
}
|
|
|
|
type SemiPhysicalMessageManager interface {
|
|
// 处理半实物仿真列车控制消息
|
|
HandleSemiPhysicalTrainControlMsg(b []byte)
|
|
// 获取半实物启动参数
|
|
GetSemiPhysicalRunConfig() *config.VobcConfig
|
|
}
|
|
|
|
type semiPhysicalTrainImpl struct {
|
|
tpapi.ThirdPartyApiService
|
|
trainControlUdpServer udp.UdpServer
|
|
trainSpeedInfoUdpClient udp.UdpClient
|
|
|
|
state tpapi.ThirdPartyApiServiceState
|
|
udpDelayRecorder *tpapi.UdpDelayRecorder
|
|
|
|
manager SemiPhysicalMessageManager
|
|
runConfig *config.VobcConfig
|
|
}
|
|
|
|
func (s *semiPhysicalTrainImpl) updateState(state tpapi.ThirdPartyApiServiceState) {
|
|
s.state = state
|
|
}
|
|
|
|
func (s *semiPhysicalTrainImpl) State() tpapi.ThirdPartyApiServiceState {
|
|
return s.state
|
|
}
|
|
|
|
func (s *semiPhysicalTrainImpl) Name() string {
|
|
return Name
|
|
}
|
|
|
|
func (s *semiPhysicalTrainImpl) handleTrainControlMsg(b []byte) {
|
|
s.udpDelayRecorder.RecordInterval()
|
|
// slog.Debug(fmt.Sprintf("半实物列车控制消息近期消息间隔: %v", s.udpDelayRecorder.GetIntervals()))
|
|
handler := s.manager
|
|
if handler != nil {
|
|
handler.HandleSemiPhysicalTrainControlMsg(b)
|
|
}
|
|
}
|
|
|
|
func (s *semiPhysicalTrainImpl) Start(manager SemiPhysicalMessageManager) {
|
|
if manager == nil {
|
|
panic("启动半实物消息服务错误: SemiPhysicalMessageManager不能为nil")
|
|
}
|
|
if s.manager != nil {
|
|
panic("启动半实物消息服务错误: 存在正在运行的任务")
|
|
}
|
|
s.runConfig = manager.GetSemiPhysicalRunConfig()
|
|
if s.runConfig == nil || s.runConfig.Ip == "" || !s.runConfig.Open {
|
|
return
|
|
}
|
|
// 初始化客户端、服务端
|
|
s.initSemiPhysical()
|
|
s.manager = manager
|
|
s.updateState(tpapi.ThirdPartyState_Normal)
|
|
s.udpDelayRecorder.Start()
|
|
}
|
|
|
|
func (s *semiPhysicalTrainImpl) Stop() {
|
|
initMutex.Lock()
|
|
defer initMutex.Unlock()
|
|
s.udpDelayRecorder.Stop()
|
|
if s.trainControlUdpServer != nil {
|
|
s.trainControlUdpServer.Close()
|
|
}
|
|
if s.trainSpeedInfoUdpClient != nil {
|
|
s.trainSpeedInfoUdpClient.Close()
|
|
}
|
|
s.manager = nil
|
|
s.updateState(tpapi.ThirdPartyState_Closed)
|
|
}
|
|
|
|
func (s *semiPhysicalTrainImpl) SendTrainControlMessage(info *message.DynamicsTrainInfo) {
|
|
sendMsg := &message.TrainSpeedMsg{}
|
|
sendMsg.DynamicsDecode(info)
|
|
s.trainSpeedInfoUdpClient.Send(sendMsg.Encode())
|
|
}
|
|
|
|
func (s *semiPhysicalTrainImpl) initSemiPhysical() {
|
|
s.trainSpeedInfoUdpClient = udp.NewClient(fmt.Sprintf("%v:%v", s.runConfig.Ip, s.runConfig.RemotePort))
|
|
s.trainControlUdpServer = udp.NewServer(fmt.Sprintf(":%d", s.runConfig.LocalPort), s.handleTrainControlMsg)
|
|
s.trainControlUdpServer.Listen()
|
|
}
|
|
|
|
var _default *semiPhysicalTrainImpl
|
|
var initMutex sync.Mutex
|
|
|
|
const Name = "半实物仿真列车"
|
|
const Interval int = 20
|
|
|
|
func Default() SemiPhysicalTrain {
|
|
initMutex.Lock()
|
|
defer initMutex.Unlock()
|
|
if _default == nil {
|
|
_default = &semiPhysicalTrainImpl{
|
|
udpDelayRecorder: tpapi.NewUdpDelayRecorder(Interval, func(err error) {
|
|
if err != nil {
|
|
_default.updateState(tpapi.ThirdPartyState_Broken)
|
|
} else {
|
|
_default.updateState(tpapi.ThirdPartyState_Normal)
|
|
}
|
|
}),
|
|
}
|
|
}
|
|
return _default
|
|
}
|