package main import ( "encoding/json" "os" "os/exec" "path/filepath" "sentinel/pkg/log" model2 "sentinel/pkg/model" "sentinel/pkg/utils" "time" ) type BusinessService struct { mqtt *MQTTService deviceID string project string cmdTopic string deviceType string } func NewBusinessService(m *MQTTService, project, deviceType, deviceID string) *BusinessService { // 根据统一规则生成 topic cmdTopic := project + "/cmd/" + deviceType + "/" + deviceID + "/#" return &BusinessService{ mqtt: m, project: project, deviceID: deviceID, cmdTopic: cmdTopic, deviceType: deviceType, } } func (b *BusinessService) Start() error { // 订阅 cmd topic if err := b.mqtt.Subscribe(b.cmdTopic, 1); err != nil { return err } b.mqtt.SetMessageHandler(b.onMQTTMessage) // 第一次连接就发送状态信息 b.SendStatusInfo() return nil } // 消息处理 func (b *BusinessService) onMQTTMessage(topic string, payload []byte) { model := model2.FromStringToMqttTopic(topic) // 是指令 if model.Domain == "cmd" { log.Println("收到指令:", model.Resource) switch model.Resource { case "ping": log.Println("pong") case "shutdown": b.handleShutdown() case "restart": b.handleRestart() case "check_update": b.handleCheckUpdate() default: log.Println("未知的命令:", model.Resource) } } } func (b *BusinessService) SendStatusInfo() { info := map[string]interface{}{ "project": utils.PROJECT, "deviceType": utils.DEVICE_TPYE, "version": utils.APP_VERSION, "online": true, "ip": utils.GetLocalIP(), "hostname": utils.GetHostname(), "mac": utils.GetMacAddress(), "os": utils.GetOSInfo(), "cpu": utils.GetCPUInfo(), "memory_total": utils.GetMemory(), "disk_total": utils.GetDisk(), "last_seen": time.Now().UTC().Format(time.RFC3339), } payload, _ := json.Marshal(info) topic := b.project + "/status/" + b.deviceType + "/" + b.deviceID + "/info" qos := byte(1) retained := true if err := b.mqtt.Publish(topic, qos, retained, payload); err != nil { log.Println("[BUS] failed to send status info:", err) } else { log.Println("[BUS] status info sent:", string(payload)) } } // 关闭程序(立即退出) func (b *BusinessService) handleShutdown() { os.Exit(0) } // 重启程序 func (b *BusinessService) handleRestart() { exe, _ := os.Executable() cmd := exec.Command(exe) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr _ = cmd.Start() os.Exit(0) } // 更新程序 func (b *BusinessService) handleCheckUpdate() { exe, _ := os.Executable() updaterPath := filepath.Join(filepath.Dir(exe), "updater") if _, err := os.Stat(updaterPath); os.IsNotExist(err) { if _, err2 := os.Stat(updaterPath + ".exe"); err2 == nil { updaterPath = updaterPath + ".exe" } else { log.Println("[BUS] updater not found") return } } cmd := exec.Command(updaterPath, "--target", exe) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Start(); err != nil { log.Println("[BUS] failed to start updater:", err) return } log.Println("[BUS] exiting main program for update") os.Exit(0) }