jl-iot/server/server.go

171 lines
4.2 KiB
Go
Raw Normal View History

package server
import (
"context"
"log/slog"
"os"
"time"
"joylink.club/iot/config"
"joylink.club/iot/dto"
"joylink.club/iot/mqtt"
"joylink.club/iot/service"
)
var iqcs *IotQcServer
type IotQcServer struct {
qcMappingService service.IotQcMappingService
qcDataPubTask service.IScheduledTask
tasks []service.IScheduledTask
state *dto.IotServiceState
cancel context.CancelFunc
}
func (s *IotQcServer) start() error {
startMqttClient()
// 注册服务请求处理
s.registerReqHandlers()
// 启动服务状态发布定时任务
iqcs.tasks = append(iqcs.tasks, service.NewScheduledTask(pubServerState, 1*time.Second))
ctx, cancel := context.WithCancel(context.Background())
s.serve(ctx)
s.cancel = cancel
return nil
}
func (s *IotQcServer) serve(ctx context.Context) {
defer s.stop()
for {
<-ctx.Done()
time.Sleep(10 * time.Millisecond)
}
}
func (s *IotQcServer) stop() error {
if s.qcDataPubTask != nil {
s.qcDataPubTask.Stop()
}
if s.qcMappingService != nil {
s.qcMappingService.Stop()
}
for _, task := range s.tasks {
task.Stop()
}
mqtt.Stop()
return nil
}
// 服务状态监测
func (s *IotQcServer) stateMonitor() *dto.IotServiceState {
if s.qcMappingService != nil {
if err := s.qcMappingService.ReportError(); err != nil {
// slog.Error("Modbus驱采映射服务报错", "err", err)
return &dto.IotServiceState{
State: dto.ServiceState_Error,
ErrMsg: err.Error(),
}
}
}
return &dto.IotServiceState{
State: dto.ServiceState_Normal,
}
}
// 注册服务请求处理
func (s *IotQcServer) registerReqHandlers() {
mqtt.RegIotQcServiceStartReqHandler(s.startIotQcMappingService)
mqtt.RegIotQcServiceStopReqHandler(s.stopIotQcMappingService)
mqtt.RegIotLogReqHandler(GetIotLog)
// 注册驱采数据写入处理
mqtt.RegIotQdHandler(s.handleQdWrite)
mqtt.RegIotCjHandler(s.handleCjWrite)
}
func (s *IotQcServer) pubQcData() {
service := s.qcMappingService
if service != nil {
mqtt.PubIotCjData(&dto.IotCj{Data: service.GetCjBytes()})
mqtt.PubIotQdData(&dto.IotQd{Data: service.GetQdBytes()})
}
}
func (s *IotQcServer) startIotQcMappingService(req *dto.IotQcServiceStartReq) *dto.IotQcServiceCommonResp {
mqcs, err := service.NewModbusQcService(req.Config)
if err != nil {
slog.Error("创建Modbus驱采映射服务失败", "err", err)
return &dto.IotQcServiceCommonResp{Code: 1, Msg: err.Error()}
}
s.qcMappingService = mqcs
s.qcDataPubTask = service.NewScheduledTask(s.pubQcData, time.Duration(req.Config.Interval)*time.Millisecond)
return &dto.IotQcServiceCommonResp{Code: 0, Msg: "成功"}
}
func (s *IotQcServer) handleQdWrite(qd *dto.IotQd) {
if s.qcMappingService != nil {
slog.Info("IOT收到并执行写入驱动数据", "data", qd.Data)
s.qcMappingService.WriteQdBytes(qd.Data)
}
}
func (s *IotQcServer) handleCjWrite(cj *dto.IotCj) {
if s.qcMappingService != nil {
slog.Info("IOT收到并执行写入采集数据", "data", cj.Data)
s.qcMappingService.WriteCjBytes(cj.Data)
}
}
func (s *IotQcServer) stopIotQcMappingService(req *dto.IotQcServiceStopReq) *dto.IotQcServiceCommonResp {
task := s.qcDataPubTask
s.qcDataPubTask = nil
if task != nil {
task.Stop()
}
service := s.qcMappingService
s.qcMappingService = nil
if service != nil {
service.Stop()
}
return &dto.IotQcServiceCommonResp{Code: 0, Msg: "成功"}
}
func StartIotQcServer() {
iqcs = &IotQcServer{
tasks: []service.IScheduledTask{},
state: &dto.IotServiceState{
State: dto.ServiceState_Normal,
},
}
iqcs.start()
}
func StopIotQcServer() {
iqcs.cancel()
}
func pubServerState() {
state := iqcs.stateMonitor()
slog.Debug("发布服务状态", "state", state.State, "msg", state.ErrMsg)
mqtt.PubIotServiceState(state)
}
func startMqttClient() {
config.LoadConfig()
mqttcfg := config.Cfg.Mqtt
cmc := &mqtt.IotMqttConfig{
AppId: mqttcfg.Topic.App,
BrokerUrl: mqttcfg.Address,
ClientId: mqttcfg.ClientId,
Username: mqttcfg.Username,
Password: mqttcfg.Password,
KeepAlive: mqttcfg.KeepAlive,
ConnectRetryDelay: mqttcfg.ConnectRetryDelay,
ConnectTimeout: mqttcfg.ConnectTimeout,
}
err := mqtt.Start(cmc)
if err != nil {
slog.Error("启动MQTT客户端失败", "error", err)
os.Exit(1)
}
}