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.
nnet/router/router.go

112 lines
2.3 KiB
Go

package router
import (
"git.noahlan.cn/noahlan/nnet/connection"
"git.noahlan.cn/noahlan/nnet/packet"
"git.noahlan.cn/noahlan/ntool/nlog"
)
type (
Handler interface {
Handle(c *connection.Connection, pkg packet.IPacket)
}
// HandlerFunc 消息处理方法
HandlerFunc func(conn *connection.Connection, pkg packet.IPacket)
Middleware func(next HandlerFunc) HandlerFunc
Route struct {
Matches any // 用于匹配的关键字段
Handler HandlerFunc // 处理方法
}
Router interface {
Handler
Register(matches any, handler Handler) error
SetNotFoundHandler(handler Handler)
}
Constructor func(Handler) Handler
)
func notFound(conn *connection.Connection, _ packet.IPacket) {
nlog.Error("handler not found")
_ = conn.SendBytes([]byte("404"))
}
func NotFoundHandler(next Handler) Handler {
return HandlerFunc(func(c *connection.Connection, packet packet.IPacket) {
h := next
if next == nil {
h = HandlerFunc(notFound)
}
// TODO write to client
h.Handle(c, packet)
})
}
func (f HandlerFunc) Handle(c *connection.Connection, pkg packet.IPacket) {
f(c, pkg)
}
type Chain struct {
constructors []Constructor
}
func NewChain(constructors ...Constructor) Chain {
return Chain{append(([]Constructor)(nil), constructors...)}
}
func (c Chain) Then(h Handler) Handler {
// TODO nil
for i := range c.constructors {
h = c.constructors[len(c.constructors)-1-i](h)
}
return h
}
func (c Chain) ThenFunc(fn HandlerFunc) Handler {
if fn == nil {
return c.Then(nil)
}
return c.Then(fn)
}
func (c Chain) Append(constructors ...Constructor) Chain {
newCons := make([]Constructor, 0, len(c.constructors)+len(constructors))
newCons = append(newCons, c.constructors...)
newCons = append(newCons, constructors...)
return Chain{newCons}
}
func (c Chain) Extend(chain Chain) Chain {
return c.Append(chain.constructors...)
}
type plainRouter struct {
handler Handler
notFound Handler
}
func NewDefaultRouter() Router {
return &plainRouter{}
}
func (p *plainRouter) Handle(c *connection.Connection, pkg packet.IPacket) {
if p.handler == nil {
return
}
p.handler.Handle(c, pkg)
}
func (p *plainRouter) Register(_ any, handler Handler) error {
p.handler = handler
return nil
}
func (p *plainRouter) SetNotFoundHandler(handler Handler) {
p.notFound = handler
}