123 lines
3.4 KiB
Go
123 lines
3.4 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"time"
|
|
|
|
"sentinel/pkg/config"
|
|
"sentinel/pkg/device"
|
|
"sentinel/pkg/docker"
|
|
"sentinel/pkg/log"
|
|
)
|
|
|
|
func main() {
|
|
deviceID := device.GetDeviceID()
|
|
|
|
// APP Logo
|
|
InitPrint(deviceID)
|
|
// Config
|
|
InitConfigFile()
|
|
// MQTT
|
|
InitMQTT(deviceID)
|
|
|
|
}
|
|
func InitConfigFile() {
|
|
// 第一次写入默认配置
|
|
cfg := config.AppConfig{
|
|
VersionCode: config.APP_VERSION,
|
|
PID: os.Getpid(),
|
|
NeedUpdate: false,
|
|
ControlState: "DEGRADED",
|
|
LastAliveAt: time.Now().Unix(),
|
|
}
|
|
|
|
// 写入文件
|
|
if err := config.WriteLocalConfig(&cfg); err != nil {
|
|
log.Println("[config] 写入初始配置失败:", err)
|
|
}
|
|
}
|
|
|
|
func InitPrint(deviceID string) {
|
|
banner := `
|
|
==============================================================================
|
|
|
|
██████ █████ ██████ ██████ ██ ██████ ██████ ██ ██ ██████
|
|
██ ██ ██ ██ ██ ████ ██ ██ ███ ██ ██
|
|
█████ ██ ██ ██ ██ █████ ██ ██ ██ ██ █████ ████ ██ ██
|
|
██ ██ ██ ██ ██ ██ ██████ ██ ██ ██ ██ ████ ██
|
|
██████ █████ █████ ██████ ██ ██ █████ ██████ ██ ██ ██
|
|
|
|
==============================================================================
|
|
`
|
|
log.Println(banner)
|
|
log.Println("Device id: "+deviceID, "\t版本号: ", config.APP_VERSION) // 第一次启动记录
|
|
}
|
|
|
|
func InitMQTT(deviceID string) {
|
|
var mqttSvc *MQTTService
|
|
firstFail := true // 标记是否第一次失败
|
|
mqttSvc = NewMQTTService(config.MQTT_BROKER, deviceID, deviceID, config.PASSWORD, 60)
|
|
for {
|
|
err := mqttSvc.Connect()
|
|
if err != nil {
|
|
if firstFail {
|
|
log.Error("物联网服务器连接失败,如未注册设备,请先注册: " + deviceID)
|
|
firstFail = false
|
|
}
|
|
time.Sleep(3 * time.Second) // 5秒后重试
|
|
continue
|
|
}
|
|
break
|
|
}
|
|
defer mqttSvc.Close()
|
|
|
|
dm, err := docker.NewDockerManager()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
biz := NewBusinessService(mqttSvc, deviceID, *dm)
|
|
|
|
for {
|
|
// MQTT业务
|
|
err := biz.Start()
|
|
if err != nil {
|
|
log.Error("business service start failed: " + err.Error())
|
|
fmt.Println("业务启动失败,5秒后重试...")
|
|
time.Sleep(5 * time.Second)
|
|
continue
|
|
}
|
|
break
|
|
}
|
|
// 第一次运行直接启动
|
|
biz.handleRestart()
|
|
|
|
// 4️⃣ T2 超时自毁检查
|
|
tickerLost := time.NewTicker(10 * time.Second)
|
|
defer tickerLost.Stop()
|
|
go func() {
|
|
for range tickerLost.C {
|
|
cfg := config.LoadConfig()
|
|
now := time.Now().Unix()
|
|
if cfg.ControlState == "DEGRADED" && now-cfg.LastAliveAt > config.DAEMON_ALIVE_GAP_SECONDS {
|
|
log.Println("[main] MQTT 长期失联,进入 CONTROL_LOST")
|
|
cfg.ControlState = "CONTROL_LOST"
|
|
cfg.LastAliveAt = time.Now().Unix()
|
|
if err := config.WriteLocalConfig(cfg); err != nil {
|
|
log.Println("[main] 写状态失败:", err)
|
|
}
|
|
// 停止业务容器
|
|
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
|
defer cancel()
|
|
dm.StopAndRemoveContainer(ctx)
|
|
// 自杀退出,让 daemon 重启
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
}()
|
|
|
|
<-make(chan struct{})
|
|
}
|