121 lines
2.8 KiB
Go
121 lines
2.8 KiB
Go
|
package interlock
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"fmt"
|
||
|
"log/slog"
|
||
|
"runtime/debug"
|
||
|
"time"
|
||
|
|
||
|
"joylink.club/bj-rtsts-server/config"
|
||
|
"joylink.club/bj-rtsts-server/third_party/message"
|
||
|
"joylink.club/bj-rtsts-server/third_party/udp"
|
||
|
)
|
||
|
|
||
|
// 联锁代理通信接口
|
||
|
type InterlockMessageManager interface {
|
||
|
CollectRelayInfo() *message.InterlockSendMsgPkg
|
||
|
HandleDriverInfo(b []byte)
|
||
|
}
|
||
|
|
||
|
// 联锁接口
|
||
|
type InterlockProxy interface {
|
||
|
// 启动联锁消息功能
|
||
|
Start(manager InterlockMessageManager)
|
||
|
// 停止联锁消息功能
|
||
|
Stop()
|
||
|
// 发送联锁采集消息
|
||
|
SendCollectMessage(b []byte)
|
||
|
}
|
||
|
|
||
|
var _default InterlockProxy
|
||
|
|
||
|
func Default() InterlockProxy {
|
||
|
if !config.Config.Interlock.Open { // TODO
|
||
|
panic("联锁接口模块未开启")
|
||
|
}
|
||
|
return _default
|
||
|
}
|
||
|
|
||
|
type interlockProxy struct {
|
||
|
driveInfoUdpServer udp.UdpServer
|
||
|
sendCollectUdpClient udp.UdpClient
|
||
|
|
||
|
manager InterlockMessageManager
|
||
|
collectInfoTaskCancel context.CancelFunc
|
||
|
}
|
||
|
|
||
|
// 驱动信息进行转发
|
||
|
func (d *interlockProxy) handleDriverInfo(b []byte) {
|
||
|
handler := d.manager
|
||
|
if handler != nil {
|
||
|
handler.HandleDriverInfo(b)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (d *interlockProxy) Start(manager InterlockMessageManager) {
|
||
|
if manager == nil {
|
||
|
panic("启动联锁消息服务错误: InterlockMessageManager不能为nil")
|
||
|
}
|
||
|
if d.manager != nil {
|
||
|
panic("启动联锁消息服务错误: 存在正在运行的任务")
|
||
|
}
|
||
|
d.manager = manager
|
||
|
ctx, cancle := context.WithCancel(context.Background())
|
||
|
go d.collectInfoStateTask(ctx)
|
||
|
d.collectInfoTaskCancel = cancle
|
||
|
}
|
||
|
|
||
|
const (
|
||
|
// 采集电路状态发送间隔,单位ms
|
||
|
InterlockMessageSendInterval = 50
|
||
|
)
|
||
|
|
||
|
// 定时发送采集电路状态任务
|
||
|
func (d *interlockProxy) collectInfoStateTask(ctx context.Context) {
|
||
|
defer func() {
|
||
|
if err := recover(); err != nil {
|
||
|
slog.Error("定时发送道岔状态任务异常", "error", err, "stack", string(debug.Stack()))
|
||
|
debug.PrintStack()
|
||
|
}
|
||
|
}()
|
||
|
for {
|
||
|
select {
|
||
|
case <-ctx.Done():
|
||
|
return
|
||
|
default:
|
||
|
}
|
||
|
collectInfoStates := d.manager.CollectRelayInfo()
|
||
|
d.sendCollectUdpClient.SendMsg(collectInfoStates)
|
||
|
time.Sleep(time.Millisecond * InterlockMessageSendInterval)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (d *interlockProxy) Stop() {
|
||
|
if d.collectInfoTaskCancel != nil {
|
||
|
d.collectInfoTaskCancel()
|
||
|
d.manager = nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (d *interlockProxy) SendCollectMessage(b []byte) {
|
||
|
d.sendCollectUdpClient.Send(b)
|
||
|
}
|
||
|
|
||
|
func newInterlockProxy() *interlockProxy {
|
||
|
d := &interlockProxy{
|
||
|
sendCollectUdpClient: udp.NewClient(fmt.Sprintf("%v:%v", config.Config.Interlock.Ip, config.Config.Interlock.RemotePort)),
|
||
|
}
|
||
|
d.driveInfoUdpServer = udp.NewServer(fmt.Sprintf(":%d", config.Config.Interlock.LocalPort), d.handleDriverInfo)
|
||
|
d.driveInfoUdpServer.Listen()
|
||
|
return d
|
||
|
}
|
||
|
|
||
|
func Init() {
|
||
|
if !config.Config.Interlock.Open { // TODO
|
||
|
return
|
||
|
}
|
||
|
slog.Info("初始化联锁接口模块")
|
||
|
_default = newInterlockProxy()
|
||
|
}
|