online.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // package online manage device online state and store it in redis.
  2. package online
  3. import (
  4. "errors"
  5. "sparrow/pkg/redispool"
  6. "sparrow/pkg/serializer"
  7. "github.com/garyburd/redigo/redis"
  8. "strconv"
  9. )
  10. const (
  11. OnlineStatusKeyPrefix = "device:onlinestatus:"
  12. )
  13. type Status struct {
  14. ClientIP string
  15. AccessRPCHost string
  16. HeartbeatInterval uint32
  17. }
  18. type Manager struct {
  19. redishost string
  20. }
  21. func NewManager(host string) *Manager {
  22. mgr := &Manager{
  23. redishost: host,
  24. }
  25. return mgr
  26. }
  27. func (mgr *Manager) GetStatus(id uint64) (*Status, error) {
  28. key := OnlineStatusKeyPrefix + strconv.FormatUint(id, 10)
  29. conn, err := redispool.GetClient(mgr.redishost)
  30. if err != nil {
  31. return nil, err
  32. }
  33. status := &Status{}
  34. // get status from redis
  35. bufferStr, err := redis.String(conn.Do("GET", key))
  36. if err != nil {
  37. return nil, err
  38. }
  39. err = serializer.String2Struct(bufferStr, status)
  40. if err != nil {
  41. return nil, err
  42. }
  43. return status, nil
  44. }
  45. func (mgr *Manager) GetOnline(id uint64, status Status) error {
  46. key := OnlineStatusKeyPrefix + strconv.FormatUint(id, 10)
  47. conn, err := redispool.GetClient(mgr.redishost)
  48. if err != nil {
  49. return err
  50. }
  51. // serialize and store the device's online status info in redis
  52. bufferStr, err := serializer.Struct2String(status)
  53. if err != nil {
  54. return err
  55. }
  56. _, err = conn.Do("SET", key, bufferStr)
  57. if err != nil {
  58. return err
  59. }
  60. _, err = conn.Do("EXPIRE", key, status.HeartbeatInterval+status.HeartbeatInterval/2)
  61. if err != nil {
  62. return err
  63. }
  64. return nil
  65. }
  66. func (mgr *Manager) SetHeartbeat(id uint64) error {
  67. status, err := mgr.GetStatus(id)
  68. if err != nil {
  69. return err
  70. }
  71. if status == nil {
  72. return errors.New("device offline.")
  73. }
  74. key := OnlineStatusKeyPrefix + strconv.FormatUint(id, 10)
  75. conn, err := redispool.GetClient(mgr.redishost)
  76. if err != nil {
  77. return err
  78. }
  79. _, err = conn.Do("EXPIRE", key, status.HeartbeatInterval+status.HeartbeatInterval/2)
  80. if err != nil {
  81. return err
  82. }
  83. return nil
  84. }
  85. func (mgr *Manager) GetOffline(id uint64) error {
  86. key := OnlineStatusKeyPrefix + strconv.FormatUint(id, 10)
  87. conn, err := redispool.GetClient(mgr.redishost)
  88. if err != nil {
  89. return err
  90. }
  91. _, err = conn.Do("DEL", key)
  92. if err != nil {
  93. return err
  94. }
  95. return nil
  96. }