|
|
@@ -40,11 +40,10 @@ func (opt *MqttClientOptions) check() error {
|
|
|
}
|
|
|
|
|
|
type MqttClient struct {
|
|
|
- client mqtt.Client
|
|
|
- clientOptions *mqtt.ClientOptions
|
|
|
+ client mqtt.Client
|
|
|
|
|
|
routersMutex *sync.Mutex
|
|
|
- routers []router.Router
|
|
|
+ routers []*router.Router
|
|
|
}
|
|
|
|
|
|
func NewMqttClient(opts *MqttClientOptions) (*MqttClient, error) {
|
|
|
@@ -57,22 +56,38 @@ func NewMqttClient(opts *MqttClientOptions) (*MqttClient, error) {
|
|
|
return nil, err
|
|
|
}
|
|
|
|
|
|
+ mqttClient := &MqttClient{
|
|
|
+ routersMutex: &sync.Mutex{},
|
|
|
+ routers: make([]*router.Router, 0),
|
|
|
+ }
|
|
|
+
|
|
|
mqttOptions := mqtt.NewClientOptions().
|
|
|
SetAutoReconnect(true).
|
|
|
SetUsername(opts.UserName).
|
|
|
SetPassword(opts.Password).
|
|
|
AddBroker(opts.Address).
|
|
|
SetClientID(opts.ClientID).
|
|
|
- SetKeepAlive(opts.KeepAliveSec).
|
|
|
- SetPingTimeout(opts.PingTimeoutSec).
|
|
|
- SetWill(opts.ClientID+"/will", "dead", 2, true)
|
|
|
-
|
|
|
- return &MqttClient{
|
|
|
- client: mqtt.NewClient(mqttOptions),
|
|
|
- clientOptions: mqttOptions,
|
|
|
- routersMutex: &sync.Mutex{},
|
|
|
- routers: make([]router.Router, 0),
|
|
|
- }, nil
|
|
|
+ SetKeepAlive(opts.KeepAliveSec*time.Second).
|
|
|
+ SetPingTimeout(opts.PingTimeoutSec*time.Second).
|
|
|
+ SetWill(opts.ClientID+"/will", "dead", 2, false).
|
|
|
+ SetOnConnectHandler(func(client mqtt.Client) {
|
|
|
+ err := mqttClient.onConnect()
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println(err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }).
|
|
|
+ SetConnectionLostHandler(func(client mqtt.Client, _ error) {
|
|
|
+ err := mqttClient.onConnectLost()
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println(err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ mqttClient.client = mqtt.NewClient(mqttOptions)
|
|
|
+
|
|
|
+ return mqttClient, nil
|
|
|
}
|
|
|
|
|
|
func DestroyMqttClient(c *MqttClient) {
|
|
|
@@ -81,7 +96,7 @@ func DestroyMqttClient(c *MqttClient) {
|
|
|
|
|
|
c.routersMutex.Lock()
|
|
|
for _, r := range c.routers {
|
|
|
- router.DestroyRouter(&r)
|
|
|
+ router.DestroyRouter(r)
|
|
|
}
|
|
|
c.routers = nil
|
|
|
c.routersMutex.Unlock()
|
|
|
@@ -91,33 +106,6 @@ func DestroyMqttClient(c *MqttClient) {
|
|
|
}
|
|
|
|
|
|
func (c *MqttClient) Connect() error {
|
|
|
- c.clientOptions.SetOnConnectHandler(func(client mqtt.Client) {
|
|
|
- c.routersMutex.Lock()
|
|
|
- defer c.routersMutex.Unlock()
|
|
|
-
|
|
|
- err := c.rangeRouters(func(r *router.Router) error {
|
|
|
- err := r.RangeItem(func(item router.Item) error {
|
|
|
- token := c.client.Subscribe(item.Topic, item.Qos, func(client mqtt.Client, message mqtt.Message) {
|
|
|
- item.CallHandlers(message.Payload())
|
|
|
- })
|
|
|
- if token.Wait(); token.Error() != nil {
|
|
|
- return token.Error()
|
|
|
- }
|
|
|
-
|
|
|
- return nil
|
|
|
- })
|
|
|
- if err != nil {
|
|
|
- return errors.New("SetOnConnectHandler订阅失败: " + err.Error())
|
|
|
- }
|
|
|
-
|
|
|
- return nil
|
|
|
- })
|
|
|
- if err != nil {
|
|
|
- fmt.Println(err)
|
|
|
- return
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
token := c.client.Connect()
|
|
|
if token.Wait(); token.Error() != nil {
|
|
|
return token.Error()
|
|
|
@@ -131,7 +119,7 @@ func (c *MqttClient) Disconnect() {
|
|
|
}
|
|
|
|
|
|
func (c *MqttClient) GetRouter(group string, handlers []router.Handler) *router.Router {
|
|
|
- r := router.NewRouter(group, handlers, func(item router.Item) error {
|
|
|
+ r := router.NewRouter(group, handlers, func(item *router.Item) error {
|
|
|
for {
|
|
|
if c.client.IsConnected() {
|
|
|
break
|
|
|
@@ -140,11 +128,18 @@ func (c *MqttClient) GetRouter(group string, handlers []router.Handler) *router.
|
|
|
time.Sleep(1 * time.Second)
|
|
|
}
|
|
|
|
|
|
- token := c.client.Subscribe(item.Topic, item.Qos, func(client mqtt.Client, message mqtt.Message) {
|
|
|
- item.CallHandlers(message.Payload())
|
|
|
+ err := item.DoIfUnSubscribe(func() error {
|
|
|
+ token := c.client.Subscribe(item.Topic, item.Qos, func(client mqtt.Client, message mqtt.Message) {
|
|
|
+ item.CallHandlers(message.Payload())
|
|
|
+ })
|
|
|
+ if token.Wait(); token.Error() != nil {
|
|
|
+ return token.Error()
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
})
|
|
|
- if token.Wait(); token.Error() != nil {
|
|
|
- return token.Error()
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
}
|
|
|
|
|
|
return nil
|
|
|
@@ -156,7 +151,7 @@ func (c *MqttClient) GetRouter(group string, handlers []router.Handler) *router.
|
|
|
}
|
|
|
|
|
|
func (c *MqttClient) Response(item *router.Item, data []byte) error {
|
|
|
- token := c.client.Publish(item.Topic+"/reply", item.Qos, item.ResponseRetained, data)
|
|
|
+ token := c.client.Publish(item.Topic+"/reply", item.Qos, false, data)
|
|
|
if token.Wait(); token.Error() != nil {
|
|
|
return token.Error()
|
|
|
}
|
|
|
@@ -164,11 +159,62 @@ func (c *MqttClient) Response(item *router.Item, data []byte) error {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
+func (c *MqttClient) onConnect() error {
|
|
|
+ err := c.rangeRouters(func(r *router.Router) error {
|
|
|
+ err := r.RangeItem(func(item *router.Item) error {
|
|
|
+ err := item.DoIfUnSubscribe(func() error {
|
|
|
+ token := c.client.Subscribe(item.Topic, item.Qos, func(client mqtt.Client, message mqtt.Message) {
|
|
|
+ item.CallHandlers(message.Payload())
|
|
|
+ })
|
|
|
+ if token.Wait(); token.Error() != nil {
|
|
|
+ return token.Error()
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+ })
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+ })
|
|
|
+ if err != nil {
|
|
|
+ return errors.New("SetOnConnectHandler订阅失败: " + err.Error())
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+ })
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func (c *MqttClient) onConnectLost() error {
|
|
|
+ err := c.rangeRouters(func(r *router.Router) error {
|
|
|
+ err := r.RangeItem(func(item *router.Item) error {
|
|
|
+ item.SetUnSubscribe()
|
|
|
+ return nil
|
|
|
+ })
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+ })
|
|
|
+ if err != nil {
|
|
|
+ return errors.New("SetOnConnectHandler订阅失败: " + err.Error())
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
func (c *MqttClient) addRouter(router *router.Router) {
|
|
|
c.routersMutex.Lock()
|
|
|
defer c.routersMutex.Unlock()
|
|
|
|
|
|
- c.routers = append(c.routers, *router)
|
|
|
+ c.routers = append(c.routers, router)
|
|
|
}
|
|
|
|
|
|
func (c *MqttClient) rangeRouters(rangeFunc func(router *router.Router) error) error {
|
|
|
@@ -176,7 +222,7 @@ func (c *MqttClient) rangeRouters(rangeFunc func(router *router.Router) error) e
|
|
|
defer c.routersMutex.Unlock()
|
|
|
|
|
|
for _, r := range c.routers {
|
|
|
- err := rangeFunc(&r)
|
|
|
+ err := rangeFunc(r)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|