|
@@ -7,6 +7,11 @@ import (
|
|
|
|
|
|
type Handler func(c *Context)
|
|
|
|
|
|
+type subscribeItem struct {
|
|
|
+ handlers []Handler
|
|
|
+ subscribed bool
|
|
|
+}
|
|
|
+
|
|
|
type Router struct {
|
|
|
Group string
|
|
|
|
|
@@ -17,19 +22,19 @@ type Router struct {
|
|
|
|
|
|
globalHandlers []Handler
|
|
|
|
|
|
- topicHandlersMutex *sync.Mutex
|
|
|
- topicHandlers map[string][]Handler
|
|
|
+ subscribeItemsMutex *sync.Mutex
|
|
|
+ subscribeItems map[string]*subscribeItem
|
|
|
}
|
|
|
|
|
|
func NewRouter(group string, globalHandlers []Handler) *Router {
|
|
|
return &Router{
|
|
|
- Group: group,
|
|
|
- mqttClient: nil,
|
|
|
- contextsMutex: &sync.Mutex{},
|
|
|
- contexts: make([]*Context, 0),
|
|
|
- globalHandlers: globalHandlers,
|
|
|
- topicHandlersMutex: &sync.Mutex{},
|
|
|
- topicHandlers: make(map[string][]Handler),
|
|
|
+ Group: group,
|
|
|
+ mqttClient: nil,
|
|
|
+ contextsMutex: &sync.Mutex{},
|
|
|
+ contexts: make([]*Context, 0),
|
|
|
+ globalHandlers: globalHandlers,
|
|
|
+ subscribeItemsMutex: &sync.Mutex{},
|
|
|
+ subscribeItems: make(map[string]*subscribeItem),
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -83,17 +88,13 @@ func (router *Router) Finish() {
|
|
|
router.mqttClient = nil
|
|
|
}
|
|
|
|
|
|
-func (router *Router) AddTopic(topic string, handlers ...Handler) error {
|
|
|
- added := router.addTopicHandlers(topic, handlers...)
|
|
|
- if !added {
|
|
|
- return nil
|
|
|
- }
|
|
|
-
|
|
|
- if router.mqttClient == nil {
|
|
|
- return nil
|
|
|
- }
|
|
|
+func (router *Router) AddGlobalHandlers(handlers ...Handler) {
|
|
|
+ router.globalHandlers = append(router.globalHandlers, handlers...)
|
|
|
+}
|
|
|
|
|
|
- err := router.mqttClient.subscribe(topic, func(topic string, data []byte) {})
|
|
|
+func (router *Router) AddTopic(topic string, handlers ...Handler) error {
|
|
|
+ allHandlers := append(router.globalHandlers, handlers...)
|
|
|
+ err := router.addAndSubscribeTopicHandlers(router.Group+topic, allHandlers...)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
@@ -102,16 +103,12 @@ func (router *Router) AddTopic(topic string, handlers ...Handler) error {
|
|
|
}
|
|
|
|
|
|
func (router *Router) subscribeTopics(client *MqttClient) {
|
|
|
+ if !client.mqttClient.IsConnected() {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
router.rangeTopicHandlers(func(topic string, handlers []Handler) {
|
|
|
- err := client.subscribe(topic, func(topic string, data []byte) {
|
|
|
- c, err := newContext(router.mqttClient, topic, data, handlers)
|
|
|
- if err != nil {
|
|
|
- logger.GetInstance().Error(err)
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- c.Next()
|
|
|
- })
|
|
|
+ err := router.subscribeMqttClient(client, topic, handlers)
|
|
|
if err != nil {
|
|
|
logger.GetInstance().Error(err)
|
|
|
return
|
|
@@ -120,6 +117,10 @@ func (router *Router) subscribeTopics(client *MqttClient) {
|
|
|
}
|
|
|
|
|
|
func (router *Router) unsubscribeTopics(client *MqttClient) {
|
|
|
+ if !client.mqttClient.IsConnected() {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
router.rangeTopicHandlers(func(topic string, handlers []Handler) {
|
|
|
err := client.unsubscribe(topic)
|
|
|
if err != nil {
|
|
@@ -129,35 +130,70 @@ func (router *Router) unsubscribeTopics(client *MqttClient) {
|
|
|
})
|
|
|
}
|
|
|
|
|
|
-func (router *Router) addTopicHandlers(topic string, handler ...Handler) bool {
|
|
|
- router.topicHandlersMutex.Lock()
|
|
|
- defer router.topicHandlersMutex.Unlock()
|
|
|
+func (router *Router) subscribeMqttClient(client *MqttClient, topic string, handlers []Handler) error {
|
|
|
+ err := client.subscribe(topic, func(topic string, data []byte) {
|
|
|
+ c, err := newContext(router.mqttClient, topic, data, handlers)
|
|
|
+ if err != nil {
|
|
|
+ logger.GetInstance().Error(err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ c.callHandlers(data)
|
|
|
+
|
|
|
+ c.Next()
|
|
|
+ })
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func (router *Router) addAndSubscribeTopicHandlers(topic string, handlers ...Handler) error {
|
|
|
+ router.subscribeItemsMutex.Lock()
|
|
|
+ defer router.subscribeItemsMutex.Unlock()
|
|
|
+
|
|
|
+ router.subscribeItems[topic] = &subscribeItem{
|
|
|
+ handlers: handlers,
|
|
|
+ subscribed: false,
|
|
|
+ }
|
|
|
+
|
|
|
+ if router.mqttClient == nil {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
|
|
|
- if router.topicHandlers[topic] != nil && len(router.topicHandlers[topic]) > 0 {
|
|
|
- return false
|
|
|
+ if !router.mqttClient.mqttClient.IsConnected() {
|
|
|
+ return nil
|
|
|
}
|
|
|
|
|
|
- router.topicHandlers[topic] = append(router.globalHandlers, handler...)
|
|
|
+ err := router.subscribeMqttClient(router.mqttClient, topic, handlers)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ router.subscribeItems[topic].subscribed = true
|
|
|
|
|
|
- return true
|
|
|
+ return nil
|
|
|
}
|
|
|
|
|
|
func (router *Router) removeTopicHandlers(topic string) {
|
|
|
- router.topicHandlersMutex.Lock()
|
|
|
- defer router.topicHandlersMutex.Unlock()
|
|
|
+ router.subscribeItemsMutex.Lock()
|
|
|
+ defer router.subscribeItemsMutex.Unlock()
|
|
|
|
|
|
- if router.topicHandlers[topic] == nil || len(router.topicHandlers[topic]) == 0 {
|
|
|
+ if router.subscribeItems[topic] == nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- delete(router.topicHandlers, topic)
|
|
|
+ delete(router.subscribeItems, topic)
|
|
|
}
|
|
|
|
|
|
func (router *Router) rangeTopicHandlers(callback func(topic string, handlers []Handler)) {
|
|
|
- router.topicHandlersMutex.Lock()
|
|
|
- defer router.topicHandlersMutex.Unlock()
|
|
|
+ router.subscribeItemsMutex.Lock()
|
|
|
+ defer router.subscribeItemsMutex.Unlock()
|
|
|
|
|
|
- for topic, topicHandlers := range router.topicHandlers {
|
|
|
- callback(topic, topicHandlers)
|
|
|
+ for topic, item := range router.subscribeItems {
|
|
|
+ if !item.subscribed {
|
|
|
+ callback(topic, item.handlers)
|
|
|
+ }
|
|
|
}
|
|
|
}
|