完善牧安云哨-中间件

This commit is contained in:
BBIT-Kai
2025-12-29 16:30:55 +08:00
parent b9b8d30ebf
commit f6f8b59c73
30 changed files with 1090 additions and 0 deletions
+131
View File
@@ -0,0 +1,131 @@
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)
}