127 lines
3.4 KiB
Go
127 lines
3.4 KiB
Go
|
// Package beijing11 北京11号线联锁通信
|
|||
|
package beijing11
|
|||
|
|
|||
|
import (
|
|||
|
"fmt"
|
|||
|
"joylink.club/bj-rtsts-server/config"
|
|||
|
"joylink.club/bj-rtsts-server/third_party/udp"
|
|||
|
"log/slog"
|
|||
|
"sync"
|
|||
|
)
|
|||
|
|
|||
|
var (
|
|||
|
initMutex = sync.Mutex{}
|
|||
|
interlockMap = make(map[string]*InterlockProxy)
|
|||
|
logTag = "[北京11号线联锁通信]"
|
|||
|
)
|
|||
|
|
|||
|
func GetInstant(c *config.InterlockConfig, msgManager MsgManager) *InterlockProxy {
|
|||
|
initMutex.Lock()
|
|||
|
defer initMutex.Unlock()
|
|||
|
if interlockMap[c.Code] == nil {
|
|||
|
interlockMap[c.Code] = &InterlockProxy{runConfig: c, msgManager: msgManager}
|
|||
|
}
|
|||
|
return interlockMap[c.Code]
|
|||
|
}
|
|||
|
|
|||
|
type MsgManager interface {
|
|||
|
HandleReadRegisterMsg(req *ReadRegisterReq) (*ReadRegisterRes, error)
|
|||
|
HandleWriteRegisterMsg(req *WriteRegisterReq) error
|
|||
|
HandleDownstreamMsg(data []byte) error
|
|||
|
CollectUpstreamMsg() []byte
|
|||
|
}
|
|||
|
|
|||
|
type msgManager struct {
|
|||
|
}
|
|||
|
|
|||
|
type InterlockProxy struct {
|
|||
|
runConfig *config.InterlockConfig //联锁通信配置
|
|||
|
msgManager MsgManager //消息获取与处理接口0
|
|||
|
client udp.UdpClient //向上位机发送数据的UDP客户端
|
|||
|
server udp.UdpServer //接收上位机数据的UDP服务端
|
|||
|
running bool //此服务正在运行的标志
|
|||
|
}
|
|||
|
|
|||
|
func (i *InterlockProxy) Start() {
|
|||
|
if i.runConfig == nil || i.runConfig.Ip == "" || !i.runConfig.Open {
|
|||
|
return
|
|||
|
}
|
|||
|
if i.running {
|
|||
|
panic("启动联锁消息服务错误: 存在正在运行的任务")
|
|||
|
}
|
|||
|
//UDP通信设施
|
|||
|
i.server = udp.NewServer(fmt.Sprintf(":%d", i.runConfig.LocalPort), i.handleUpperData)
|
|||
|
err := i.server.Listen()
|
|||
|
if err != nil {
|
|||
|
panic("启动联锁消息服务错误:无法启动UDP服务")
|
|||
|
}
|
|||
|
i.running = true
|
|||
|
i.client = udp.NewClient(fmt.Sprintf("%v:%v", i.runConfig.Ip, i.runConfig.RemotePort))
|
|||
|
}
|
|||
|
|
|||
|
// 处理来自上位机的数据
|
|||
|
func (i *InterlockProxy) handleUpperData(data []byte) {
|
|||
|
baseData := &BaseStruct{}
|
|||
|
err := baseData.Decode(data)
|
|||
|
if err != nil {
|
|||
|
slog.Error(logTag + "数据解析出错:" + err.Error())
|
|||
|
return
|
|||
|
}
|
|||
|
switch baseData.ControlWord {
|
|||
|
case ControlWord.ReadRegister:
|
|||
|
req := &ReadRegisterReq{}
|
|||
|
err := req.Decode(baseData.Data)
|
|||
|
if err != nil {
|
|||
|
slog.Error(logTag + "读寄存器数据解析出错:" + err.Error())
|
|||
|
return
|
|||
|
}
|
|||
|
res, err := i.msgManager.HandleReadRegisterMsg(req)
|
|||
|
if err != nil {
|
|||
|
slog.Error(logTag + "读寄存器数据处理出错:" + err.Error())
|
|||
|
return
|
|||
|
}
|
|||
|
resData := &BaseStruct{
|
|||
|
ID: baseData.ID,
|
|||
|
ControlWord: ControlWord.Response,
|
|||
|
Data: res.Encode(),
|
|||
|
}
|
|||
|
i.SendToUpper(resData.Encode())
|
|||
|
case ControlWord.WriteRegister:
|
|||
|
req := &WriteRegisterReq{}
|
|||
|
err := req.Decode(baseData.Data)
|
|||
|
if err != nil {
|
|||
|
slog.Error(logTag + "写寄存器数据解析出错:" + err.Error())
|
|||
|
return
|
|||
|
}
|
|||
|
err = i.msgManager.HandleWriteRegisterMsg(req)
|
|||
|
if err != nil {
|
|||
|
slog.Error(logTag + "写寄存器数据处理出错:" + err.Error())
|
|||
|
return
|
|||
|
}
|
|||
|
case ControlWord.DownStream:
|
|||
|
err = i.msgManager.HandleDownstreamMsg(baseData.Data)
|
|||
|
if err != nil {
|
|||
|
slog.Error(logTag + "下行数据处理出错:" + err.Error())
|
|||
|
return
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
func (i *InterlockProxy) SendToUpper(data []byte) {
|
|||
|
err := i.client.Send(data)
|
|||
|
slog.Error(logTag + "向上位机发送数据失败:" + err.Error())
|
|||
|
}
|
|||
|
|
|||
|
func (i *InterlockProxy) Stop() {
|
|||
|
initMutex.Lock()
|
|||
|
defer initMutex.Unlock()
|
|||
|
delete(interlockMap, i.runConfig.Code)
|
|||
|
if i.client != nil {
|
|||
|
i.client.Close()
|
|||
|
}
|
|||
|
if i.server != nil {
|
|||
|
i.server.Close()
|
|||
|
}
|
|||
|
i.running = false
|
|||
|
}
|