增加心跳
This commit is contained in:
148
internal/service/heartbeat.go
Normal file
148
internal/service/heartbeat.go
Normal file
@@ -0,0 +1,148 @@
|
||||
// Package service 提供各种业务服务功能
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"git.huangwc.com/pig/pig-farm-controller/internal/config"
|
||||
"git.huangwc.com/pig/pig-farm-controller/internal/logs"
|
||||
"git.huangwc.com/pig/pig-farm-controller/internal/storage/repository"
|
||||
)
|
||||
|
||||
// HeartbeatService 心跳服务,负责管理设备的心跳检测
|
||||
type HeartbeatService struct {
|
||||
// websocketService WebSocket服务
|
||||
websocketService *WebSocketService
|
||||
|
||||
// deviceStatusPool 设备状态池
|
||||
deviceStatusPool *DeviceStatusPool
|
||||
|
||||
// deviceRepo 设备仓库
|
||||
deviceRepo repository.DeviceRepo
|
||||
|
||||
// logger 日志记录器
|
||||
logger *logs.Logger
|
||||
|
||||
// 心跳间隔
|
||||
heartbeatInterval time.Duration
|
||||
|
||||
// 手动心跳触发器
|
||||
triggerChan chan struct{}
|
||||
|
||||
// ticker 心跳定时器
|
||||
ticker *time.Ticker
|
||||
|
||||
// ctx 上下文
|
||||
ctx context.Context
|
||||
|
||||
// cancel 取消函数
|
||||
cancel context.CancelFunc
|
||||
}
|
||||
|
||||
// NewHeartbeatService 创建心跳服务实例
|
||||
func NewHeartbeatService(websocketService *WebSocketService, deviceStatusPool *DeviceStatusPool, deviceRepo repository.DeviceRepo, config *config.Config) *HeartbeatService {
|
||||
return &HeartbeatService{
|
||||
websocketService: websocketService,
|
||||
deviceStatusPool: deviceStatusPool,
|
||||
deviceRepo: deviceRepo,
|
||||
logger: logs.NewLogger(),
|
||||
heartbeatInterval: time.Duration(config.GetHeartbeatInterval()) * time.Second,
|
||||
triggerChan: make(chan struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
// Start 启动心跳服务
|
||||
func (hs *HeartbeatService) Start() {
|
||||
// 创建上下文
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
hs.cancel = cancel
|
||||
|
||||
// 创建定时器
|
||||
hs.logger.Info(fmt.Sprintf("设置心跳间隔为 %d 秒", int(hs.heartbeatInterval.Seconds())))
|
||||
hs.ticker = time.NewTicker(hs.heartbeatInterval)
|
||||
|
||||
// 启动心跳goroutine
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case <-hs.ticker.C:
|
||||
hs.handleHeartbeat()
|
||||
case <-hs.triggerChan:
|
||||
hs.handleHeartbeat()
|
||||
case <-ctx.Done():
|
||||
hs.logger.Info("心跳服务已停止")
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
hs.logger.Info("心跳服务已启动")
|
||||
}
|
||||
|
||||
// Stop 停止心跳服务
|
||||
func (hs *HeartbeatService) Stop() {
|
||||
if hs == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if hs.ticker != nil {
|
||||
hs.ticker.Stop()
|
||||
}
|
||||
|
||||
if hs.cancel != nil {
|
||||
hs.cancel()
|
||||
}
|
||||
|
||||
hs.logger.Info("[Heartbeat] 心跳任务停止指令已发送")
|
||||
}
|
||||
|
||||
// TriggerManualHeartbeat 手动触发心跳检测
|
||||
func (hs *HeartbeatService) TriggerManualHeartbeat() {
|
||||
hs.logger.Info("收到手动触发心跳检测请求")
|
||||
hs.triggerChan <- struct{}{}
|
||||
hs.logger.Info("手动心跳检测完成")
|
||||
}
|
||||
|
||||
// TriggerManualHeartbeatAsync 手动触发心跳检测且不等待检测结果
|
||||
func (hs *HeartbeatService) TriggerManualHeartbeatAsync() {
|
||||
hs.logger.Info("收到手动触发异步心跳检测请求")
|
||||
go func() {
|
||||
hs.triggerChan <- struct{}{}
|
||||
hs.logger.Info("手动心跳检测完成")
|
||||
}()
|
||||
}
|
||||
|
||||
// sendHeartbeat 发送心跳包到所有中继设备
|
||||
func (hs *HeartbeatService) handleHeartbeat() {
|
||||
// 记录心跳开始日志
|
||||
hs.logger.Debug("开始发送心跳包")
|
||||
|
||||
// 获取所有已连接的设备
|
||||
connectedDevices := hs.websocketService.GetConnectedDevices()
|
||||
|
||||
// 遍历所有连接的设备并发送心跳包
|
||||
for _, deviceID := range connectedDevices {
|
||||
// 发送心跳包到设备
|
||||
response, err := hs.websocketService.SendCommandAndWait(deviceID, "heartbeat", nil, 0)
|
||||
if err != nil {
|
||||
hs.logger.Error(fmt.Sprintf("向设备 %s 发送心跳包失败: %v", deviceID, err))
|
||||
// 更新设备状态为离线
|
||||
hs.deviceStatusPool.SetStatus(deviceID, &DeviceStatus{
|
||||
Active: false,
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
// 记录收到心跳响应
|
||||
hs.logger.Debug(fmt.Sprintf("收到来自设备 %s 的心跳响应: %+v", deviceID, response))
|
||||
|
||||
// 更新设备状态为在线
|
||||
hs.deviceStatusPool.SetStatus(deviceID, &DeviceStatus{
|
||||
Active: true,
|
||||
})
|
||||
}
|
||||
|
||||
hs.logger.Debug("心跳包发送完成")
|
||||
}
|
||||
Reference in New Issue
Block a user