|
|
package router
|
|
|
|
|
|
import (
|
|
|
ctxpkg "github.com/noahlann/nnet/pkg/context"
|
|
|
protocolpkg "github.com/noahlann/nnet/pkg/protocol"
|
|
|
)
|
|
|
|
|
|
// MatchInput 匹配输入
|
|
|
type MatchInput struct {
|
|
|
// Raw 原始数据(未解码)
|
|
|
Raw []byte
|
|
|
// Header 协议帧头(如果存在)
|
|
|
Header protocolpkg.FrameHeader
|
|
|
// DataBytes 协议数据部分的原始字节(协议解码后、codec解码前)
|
|
|
DataBytes []byte
|
|
|
// Data 协议数据部分的解码结果(codec解码后的Go对象)
|
|
|
Data interface{}
|
|
|
}
|
|
|
|
|
|
// Matcher 路由匹配器接口
|
|
|
type Matcher interface {
|
|
|
// Match 根据输入和上下文执行匹配
|
|
|
Match(input MatchInput, ctx ctxpkg.Context) bool
|
|
|
// Priority 获取优先级(数字越大优先级越高)
|
|
|
Priority() int
|
|
|
}
|
|
|
|
|
|
// StringMatcher 字符串匹配器(针对原始数据)
|
|
|
type StringMatcher struct {
|
|
|
pattern string
|
|
|
priority int
|
|
|
}
|
|
|
|
|
|
// NewStringMatcher 创建字符串匹配器
|
|
|
func NewStringMatcher(pattern string) *StringMatcher {
|
|
|
return &StringMatcher{
|
|
|
pattern: pattern,
|
|
|
priority: 100, // 默认优先级
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// WithPriority 设置优先级
|
|
|
func (m *StringMatcher) WithPriority(priority int) *StringMatcher {
|
|
|
m.priority = priority
|
|
|
return m
|
|
|
}
|
|
|
|
|
|
// Match 匹配字符串
|
|
|
func (m *StringMatcher) Match(input MatchInput, ctx ctxpkg.Context) bool {
|
|
|
dataBytes := input.Raw
|
|
|
if len(input.DataBytes) > 0 {
|
|
|
dataBytes = input.DataBytes
|
|
|
}
|
|
|
|
|
|
// 支持精确匹配和前缀匹配
|
|
|
dataStr := string(dataBytes)
|
|
|
if dataStr == m.pattern {
|
|
|
return true
|
|
|
}
|
|
|
// 支持通配符匹配(简单实现)
|
|
|
if len(m.pattern) > 0 && m.pattern[len(m.pattern)-1] == '*' {
|
|
|
prefix := m.pattern[:len(m.pattern)-1]
|
|
|
if len(dataStr) >= len(prefix) && dataStr[:len(prefix)] == prefix {
|
|
|
return true
|
|
|
}
|
|
|
}
|
|
|
return false
|
|
|
}
|
|
|
|
|
|
// Priority 获取优先级
|
|
|
func (m *StringMatcher) Priority() int {
|
|
|
return m.priority
|
|
|
}
|
|
|
|
|
|
// Pattern 获取匹配模式
|
|
|
func (m *StringMatcher) Pattern() string {
|
|
|
return m.pattern
|
|
|
}
|
|
|
|
|
|
// CompositeMatcher 组合匹配器(支持 AND / OR)
|
|
|
type CompositeMatcher struct {
|
|
|
matchers []Matcher
|
|
|
mode string // "and" or "or"
|
|
|
priority int
|
|
|
}
|
|
|
|
|
|
// NewAndMatcher 创建 AND 组合匹配器(全部子匹配器需匹配)
|
|
|
func NewAndMatcher(matchers ...Matcher) *CompositeMatcher {
|
|
|
return &CompositeMatcher{
|
|
|
matchers: matchers,
|
|
|
mode: "and",
|
|
|
priority: 100, // 默认优先级
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// NewOrMatcher 创建 OR 组合匹配器(任一子匹配器匹配即可)
|
|
|
func NewOrMatcher(matchers ...Matcher) *CompositeMatcher {
|
|
|
return &CompositeMatcher{
|
|
|
matchers: matchers,
|
|
|
mode: "or",
|
|
|
priority: 100, // 默认优先级
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// WithPriority 设置优先级
|
|
|
func (m *CompositeMatcher) WithPriority(priority int) *CompositeMatcher {
|
|
|
m.priority = priority
|
|
|
return m
|
|
|
}
|
|
|
|
|
|
// Match 组合匹配
|
|
|
func (m *CompositeMatcher) Match(input MatchInput, ctx ctxpkg.Context) bool {
|
|
|
if len(m.matchers) == 0 {
|
|
|
return false
|
|
|
}
|
|
|
|
|
|
switch m.mode {
|
|
|
case "and":
|
|
|
for _, child := range m.matchers {
|
|
|
if child == nil || !child.Match(input, ctx) {
|
|
|
return false
|
|
|
}
|
|
|
}
|
|
|
return true
|
|
|
case "or":
|
|
|
for _, child := range m.matchers {
|
|
|
if child != nil && child.Match(input, ctx) {
|
|
|
return true
|
|
|
}
|
|
|
}
|
|
|
return false
|
|
|
default:
|
|
|
return false
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// Priority 获取优先级
|
|
|
func (m *CompositeMatcher) Priority() int {
|
|
|
return m.priority
|
|
|
}
|