mqtthandler.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. package controllers
  2. import (
  3. "context"
  4. "sync"
  5. "time"
  6. "github.com/astaxie/beego"
  7. "lc/common/mqtt"
  8. )
  9. var _mqtthandleronce sync.Once
  10. var _mqtthandlersingle *MqttHandler
  11. func GetMqttHandler() *MqttHandler {
  12. _mqtthandleronce.Do(func() {
  13. _mqtthandlersingle = NewMqttHandler(beego.AppConfig.String("mqtt.server"), beego.AppConfig.String("mqtt.user"),
  14. beego.AppConfig.String("mqtt.password"), 3000)
  15. })
  16. return _mqtthandlersingle
  17. }
  18. type MqttHandler struct {
  19. mqtt *mqtt.Client
  20. mu sync.Mutex
  21. mapTopics map[string]mqtt.QOS
  22. Timeout uint //超时时间,毫秒为单位
  23. }
  24. func NewMqttHandler(server, user, password string, timeout uint) *MqttHandler {
  25. o := MqttHandler{
  26. mapTopics: make(map[string]mqtt.QOS),
  27. Timeout: timeout,
  28. }
  29. client, err := mqtt.NewClient(mqtt.ClientOptions{
  30. Servers: []string{server},
  31. ClientID: beego.AppConfig.String("mqtt.id"),
  32. Username: user,
  33. Password: password,
  34. AutoReconnect: true,
  35. }, &o)
  36. if client == nil || err != nil {
  37. beego.Error("未配置 MQTT Server")
  38. panic("未配置 MQTT Server")
  39. return nil
  40. }
  41. o.mqtt = client
  42. ctx, cancel := o.Ctx()
  43. defer cancel()
  44. err = client.Connect(ctx)
  45. return &o
  46. }
  47. func (o *MqttHandler) ConnectionLostHandler(err error) {
  48. beego.Error("MqttHandler.ConnectionLostHandler:MQTT连接已经断开,原因:", err.Error())
  49. }
  50. func (o *MqttHandler) OnConnectHandler() {
  51. beego.Debug("MqttHandler.OnConnectHandler:MQTT连接成功")
  52. //连接成功则订阅主题
  53. for k, v := range o.mapTopics {
  54. o.Subscribe(k, v)
  55. }
  56. }
  57. func (o *MqttHandler) GetWill() (string, string) {
  58. return "", ""
  59. }
  60. func (o *MqttHandler) Connect() error {
  61. if !o.mqtt.IsConnected() {
  62. ctx, cancel := o.Ctx()
  63. defer cancel()
  64. return o.mqtt.Connect(ctx)
  65. }
  66. return nil
  67. }
  68. func (o *MqttHandler) IsConnected() bool {
  69. return o.mqtt.IsConnected()
  70. }
  71. func (o *MqttHandler) Publish(topic string, payload []byte, qos mqtt.QOS) error {
  72. ctx, cancel := o.Ctx()
  73. defer cancel()
  74. return o.mqtt.Publish(ctx, topic, payload, qos)
  75. }
  76. func (o *MqttHandler) PublishString(topic string, payload string, qos mqtt.QOS) error {
  77. ctx, cancel := o.Ctx()
  78. defer cancel()
  79. return o.mqtt.PublishString(ctx, topic, payload, qos)
  80. }
  81. func (o *MqttHandler) PublishJSON(topic string, payload interface{}, qos mqtt.QOS) error {
  82. ctx, cancel := o.Ctx()
  83. defer cancel()
  84. return o.mqtt.PublishJSON(ctx, topic, payload, qos)
  85. }
  86. func (o *MqttHandler) Subscribe(topic string, qos mqtt.QOS) error {
  87. o.mu.Lock()
  88. defer o.mu.Unlock()
  89. if _, ok := o.mapTopics[topic]; !ok {
  90. o.mapTopics[topic] = qos
  91. }
  92. ctx, cancel := o.Ctx()
  93. defer cancel()
  94. return o.mqtt.Subscribe(ctx, topic, qos)
  95. }
  96. func (o *MqttHandler) Unsubscribe(ctx context.Context, topic string) error {
  97. o.mu.Lock()
  98. defer o.mu.Unlock()
  99. if _, ok := o.mapTopics[topic]; ok {
  100. delete(o.mapTopics, topic)
  101. }
  102. ctx, cancel := o.Ctx()
  103. defer cancel()
  104. return o.mqtt.Unsubscribe(ctx, topic)
  105. }
  106. func (o *MqttHandler) Handle(topic string, handler mqtt.MessageHandler) mqtt.Route {
  107. return o.mqtt.Handle(topic, handler)
  108. }
  109. func (o *MqttHandler) Ctx() (context.Context, context.CancelFunc) {
  110. return context.WithTimeout(context.Background(), time.Millisecond*time.Duration(o.Timeout))
  111. }