online.go 2.2 KB

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