You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
2.3 KiB
90 lines
2.3 KiB
package service
|
|
|
|
import (
|
|
"time"
|
|
|
|
"laic-backend/cache"
|
|
"laic-backend/common"
|
|
"laic-backend/logger"
|
|
"laic-backend/model"
|
|
)
|
|
|
|
func heartbeatTimeout() uint {
|
|
if common.AppConf != nil && common.AppConf.Heartbeat.TimeoutSeconds > 0 {
|
|
return uint(common.AppConf.Heartbeat.TimeoutSeconds)
|
|
}
|
|
return 30
|
|
}
|
|
|
|
func refreshDeviceHeartbeat(key string) {
|
|
if err := common.SetValueWithExpired(key, "1", heartbeatTimeout()); err != nil {
|
|
logger.WARN("刷新设备心跳失败:", err)
|
|
}
|
|
}
|
|
|
|
func expireDeviceHeartbeats() {
|
|
dockMembers, err := common.SetMembers(cache.OnlineDockSetKey)
|
|
if err != nil {
|
|
logger.WARN("扫描机巢在线状态失败:", err)
|
|
} else {
|
|
for _, dockID := range dockMembers {
|
|
removed, e := common.SetRemoveIfKeyMissing(cache.OnlineDockSetKey, cache.DockHeartbeatKeyOf(dockID), dockID)
|
|
if e != nil {
|
|
logger.WARN("检查机巢心跳失败:", e)
|
|
continue
|
|
}
|
|
if removed {
|
|
markDockOffline(dockID)
|
|
}
|
|
}
|
|
}
|
|
|
|
droneMembers, err := common.SetMembers(cache.OnlineDroneSetKey)
|
|
if err != nil {
|
|
logger.WARN("扫描无人机在线状态失败:", err)
|
|
return
|
|
}
|
|
for _, droneSN := range droneMembers {
|
|
removed, e := common.SetRemoveIfKeyMissing(cache.OnlineDroneSetKey, cache.DroneHeartbeatKeyOf(droneSN), droneSN)
|
|
if e != nil {
|
|
logger.WARN("检查无人机心跳失败:", e)
|
|
continue
|
|
}
|
|
if removed {
|
|
markDroneOffline(droneSN)
|
|
}
|
|
}
|
|
}
|
|
|
|
func markDockOffline(dockID string) {
|
|
result := common.DB.Model(&model.Dock{}).
|
|
Where("dock_id = ? AND status = ?", dockID, "online").
|
|
Update("status", "offline")
|
|
if result.Error != nil {
|
|
logger.WARN("更新机巢离线状态失败:", result.Error)
|
|
return
|
|
}
|
|
if result.RowsAffected > 0 {
|
|
broadcast("dock.status", map[string]any{"dockId": dockID, "online": false})
|
|
}
|
|
}
|
|
|
|
func markDroneOffline(droneSN string) {
|
|
result := common.DB.Model(&model.Drone{}).
|
|
Where("drone_sn = ? AND status = ?", droneSN, "online").
|
|
Update("status", "offline")
|
|
if result.Error != nil {
|
|
logger.WARN("更新无人机离线状态失败:", result.Error)
|
|
return
|
|
}
|
|
if result.RowsAffected > 0 {
|
|
broadcast("drone.status", map[string]any{"droneSn": droneSN, "online": false})
|
|
}
|
|
}
|
|
|
|
func heartbeatScanInterval() time.Duration {
|
|
if common.AppConf != nil && common.AppConf.Heartbeat.ScanSeconds > 0 {
|
|
return time.Duration(common.AppConf.Heartbeat.ScanSeconds) * time.Second
|
|
}
|
|
return 5 * time.Second
|
|
}
|
|
|