// 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 }