package online import ( "errors" "github.com/gogf/gf/database/gredis" "github.com/gogf/gf/util/gconv" ) const ( KeyPrefix = "device:onlinestatus:" ) type Status struct { ClientIP string AccessRPCHost string HeartbeatInterval uint32 } type Manager struct { redisClient *gredis.Redis } func NewManager(host string, port, db int) *Manager { red := gredis.New(&gredis.Config{ Host: host, Port: port, Db: db, MaxActive: 100, }) mgr := &Manager{ redisClient: red, } return mgr } func (mgr *Manager) GetStatus(id string) (*Status, error) { key := KeyPrefix + id status := new(Status) // get status from redis result, err := mgr.redisClient.DoVar("GET", key) if err != nil { return nil, err } err = result.Struct(status) if err != nil { return nil, err } return status, nil } func (mgr *Manager) GetOnline(id string, status Status) error { key := KeyPrefix + id buffStr := gconv.String(&status) _, err := mgr.redisClient.Do("SET", key, buffStr) if err != nil { return err } _, err = mgr.redisClient.Do("EXPIRE", key, status.HeartbeatInterval+status.HeartbeatInterval/2) if err != nil { return err } return nil } func (mgr *Manager) GetOnlineV2(id string, status Status) error { key := KeyPrefix + id buffStr := gconv.String(&status) _, err := mgr.redisClient.Do("SET", key, buffStr) if err != nil { return err } _, err = mgr.redisClient.Do("EXPIRE", key, -1) if err != nil { return err } return nil } func (mgr *Manager) SetHeartbeat(id string) error { status, err := mgr.GetStatus(id) if err != nil { return err } if status == nil { return errors.New("device offline") } key := KeyPrefix + id _, err = mgr.redisClient.Do("EXPIRE", key, status.HeartbeatInterval+status.HeartbeatInterval/2) if err != nil { return err } return nil } func (mgr *Manager) GetOffline(id string) error { key := KeyPrefix + id _, err := mgr.redisClient.Do("DEL", key) if err != nil { return err } return nil }