mirror of
https://github.com/lucacasonato/mqtt.git
synced 2025-09-27 11:12:11 +08:00
Added routing and subscribing
This commit is contained in:
77
router.go
Normal file
77
router.go
Normal file
@@ -0,0 +1,77 @@
|
||||
package mqtt
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type router struct {
|
||||
routes []route
|
||||
lock sync.RWMutex
|
||||
}
|
||||
|
||||
func newRouter() *router {
|
||||
return &router{routes: []route{}, lock: sync.RWMutex{}}
|
||||
}
|
||||
|
||||
type route struct {
|
||||
topic string
|
||||
handler MessageHandler
|
||||
}
|
||||
|
||||
func match(route []string, topic []string) bool {
|
||||
if len(route) == 0 {
|
||||
return len(topic) == 0
|
||||
}
|
||||
|
||||
if len(topic) == 0 {
|
||||
return route[0] == "#"
|
||||
}
|
||||
|
||||
if route[0] == "#" {
|
||||
return true
|
||||
}
|
||||
|
||||
if (route[0] == "+") || (route[0] == topic[0]) {
|
||||
return match(route[1:], topic[1:])
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func routeIncludesTopic(route, topic string) bool {
|
||||
return match(routeSplit(route), strings.Split(topic, "/"))
|
||||
}
|
||||
|
||||
func routeSplit(route string) []string {
|
||||
var result []string
|
||||
if strings.HasPrefix(route, "$share") {
|
||||
result = strings.Split(route, "/")[2:]
|
||||
} else {
|
||||
result = strings.Split(route, "/")
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (r *route) match(message *Message) bool {
|
||||
return r.topic == message.Topic() || routeIncludesTopic(r.topic, message.Topic())
|
||||
}
|
||||
|
||||
func (r *router) addRoute(topic string, handler MessageHandler) {
|
||||
if handler != nil {
|
||||
r.lock.Lock()
|
||||
r.routes = append(r.routes, route{topic: topic, handler: handler})
|
||||
r.lock.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func (r *router) match(message *Message) []route {
|
||||
routes := []route{}
|
||||
r.lock.RLock()
|
||||
for _, route := range r.routes {
|
||||
if route.match(message) {
|
||||
routes = append(routes, route)
|
||||
}
|
||||
}
|
||||
r.lock.RUnlock()
|
||||
return routes
|
||||
}
|
Reference in New Issue
Block a user