You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
2.5 KiB
Go
91 lines
2.5 KiB
Go
package router
|
|
|
|
import (
|
|
"sort"
|
|
"sync"
|
|
|
|
"github.com/noahlann/nnet/internal/router/matcher"
|
|
ctxpkg "github.com/noahlann/nnet/pkg/context"
|
|
"github.com/noahlann/nnet/pkg/errors"
|
|
"github.com/noahlann/nnet/pkg/router"
|
|
)
|
|
|
|
// routerImpl 路由器实现
|
|
type routerImpl struct {
|
|
routes []*route
|
|
mu sync.RWMutex
|
|
}
|
|
|
|
// NewRouter 创建新路由器
|
|
func NewRouter() router.Router {
|
|
return &routerImpl{
|
|
routes: make([]*route, 0),
|
|
}
|
|
}
|
|
|
|
// Register 注册路由
|
|
func (r *routerImpl) Register(matcher router.Matcher, handler router.Handler, opts ...router.RouteOption) router.Route {
|
|
r.mu.Lock()
|
|
defer r.mu.Unlock()
|
|
|
|
// 应用路由选项
|
|
config := &router.RouteConfig{}
|
|
for _, opt := range opts {
|
|
opt(config)
|
|
}
|
|
|
|
rt := newRoute(matcher, handler, config)
|
|
r.routes = append(r.routes, rt)
|
|
|
|
// 按优先级排序(优先级高的在前)
|
|
sort.Slice(r.routes, func(i, j int) bool {
|
|
return r.routes[i].matcher.Priority() > r.routes[j].matcher.Priority()
|
|
})
|
|
|
|
return rt
|
|
}
|
|
|
|
// RegisterString 注册字符串路由
|
|
func (r *routerImpl) RegisterString(pattern string, handler router.Handler, opts ...router.RouteOption) router.Route {
|
|
matcher := router.NewStringMatcher(pattern)
|
|
return r.Register(matcher, handler, opts...)
|
|
}
|
|
|
|
// RegisterFrameHeader 注册帧头匹配路由
|
|
func (r *routerImpl) RegisterFrameHeader(field, operator string, value interface{}, handler router.Handler, opts ...router.RouteOption) router.Route {
|
|
m := matcher.NewFrameHeaderMatcher(field, operator, value)
|
|
return r.Register(m, handler, opts...)
|
|
}
|
|
|
|
// RegisterFrameData 注册帧数据匹配路由
|
|
func (r *routerImpl) RegisterFrameData(path, operator string, value interface{}, handler router.Handler, opts ...router.RouteOption) router.Route {
|
|
m := matcher.NewFrameDataMatcher(path, operator, value)
|
|
return r.Register(m, handler, opts...)
|
|
}
|
|
|
|
// RegisterCustom 注册自定义匹配路由
|
|
func (r *routerImpl) RegisterCustom(fn func(input router.MatchInput, ctx ctxpkg.Context) bool, handler router.Handler, opts ...router.RouteOption) router.Route {
|
|
m := router.NewCustomMatcher(fn)
|
|
return r.Register(m, handler, opts...)
|
|
}
|
|
|
|
// Group 创建路由分组
|
|
func (r *routerImpl) Group() router.RouterGroup {
|
|
return newRouterGroup(r, "")
|
|
}
|
|
|
|
// Match 匹配路由
|
|
func (r *routerImpl) Match(input router.MatchInput, ctx ctxpkg.Context) (router.Route, router.Handler, error) {
|
|
r.mu.RLock()
|
|
defer r.mu.RUnlock()
|
|
|
|
// 按优先级顺序匹配
|
|
for _, route := range r.routes {
|
|
if route.matcher.Match(input, ctx) {
|
|
return route, route.Handler(), nil
|
|
}
|
|
}
|
|
|
|
return nil, nil, errors.ErrRouteNotFound
|
|
}
|