mirror of
				https://github.com/eolinker/apinto
				synced 2025-10-31 03:56:24 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			125 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			125 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package router_http
 | |
| 
 | |
| import (
 | |
| 	"sync"
 | |
| 
 | |
| 	"github.com/eolinker/eosc/log"
 | |
| 
 | |
| 	http_context "github.com/eolinker/goku/node/http-context"
 | |
| 
 | |
| 	"github.com/valyala/fasthttp"
 | |
| 
 | |
| 	"github.com/eolinker/eosc"
 | |
| )
 | |
| 
 | |
| var _ IRouter = (*Router)(nil)
 | |
| 
 | |
| //IRouter 路由树的接口
 | |
| type IRouter interface {
 | |
| 	SetRouter(id string, config *Config) error
 | |
| 	Count() int
 | |
| 	Del(id string) int
 | |
| 	Handler(ctx *fasthttp.RequestCtx)
 | |
| }
 | |
| 
 | |
| type IRouterFilter interface {
 | |
| 	DoFilter(ctx *http_context.Context) (isContinue bool, err error)
 | |
| }
 | |
| 
 | |
| //Router 实现了路由树接口
 | |
| type Router struct {
 | |
| 	locker  sync.Locker
 | |
| 	data    eosc.IUntyped
 | |
| 	match   IMatcher
 | |
| 	handler fasthttp.RequestHandler
 | |
| 	chain   []IRouterFilter
 | |
| }
 | |
| 
 | |
| //NewRouter 新建路由树
 | |
| func NewRouter() *Router {
 | |
| 	return &Router{
 | |
| 		locker: &sync.Mutex{},
 | |
| 		data:   eosc.NewUntyped(),
 | |
| 	}
 | |
| }
 | |
| 
 | |
| //Count 返回路由树中配置实例的数量
 | |
| func (r *Router) Count() int {
 | |
| 
 | |
| 	return r.data.Count()
 | |
| }
 | |
| 
 | |
| //Handler 路由树的handler方法
 | |
| func (r *Router) Handler(requestCtx *fasthttp.RequestCtx) {
 | |
| 	match := r.match
 | |
| 	if r.match == nil {
 | |
| 		requestCtx.NotFound()
 | |
| 		return
 | |
| 	}
 | |
| 	log.Debug("router handler", requestCtx.Request.String())
 | |
| 	ctx := http_context.NewContext(requestCtx)
 | |
| 	// TODO: 执行全局的Filter
 | |
| 	h, e, has := match.Match(ctx.Request())
 | |
| 	if !has {
 | |
| 		requestCtx.NotFound()
 | |
| 		return
 | |
| 	}
 | |
| 	h.Handle(ctx, NewEndPoint(e))
 | |
| 	for _, c := range r.chain {
 | |
| 
 | |
| 	}
 | |
| 
 | |
| }
 | |
| 
 | |
| //SetRouter 将路由配置加入到路由树中
 | |
| func (r *Router) SetRouter(id string, config *Config) error {
 | |
| 	r.locker.Lock()
 | |
| 	defer r.locker.Unlock()
 | |
| 	data := r.data.Clone()
 | |
| 	data.Set(id, config)
 | |
| 	//重新生成路由树
 | |
| 	m, err := parseData(data)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	r.match = m
 | |
| 	r.data = data
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| //Del 将某个路由从路由树中删去
 | |
| func (r *Router) Del(id string) int {
 | |
| 	r.locker.Lock()
 | |
| 	defer r.locker.Unlock()
 | |
| 
 | |
| 	data := r.data.Clone()
 | |
| 	data.Del(id)
 | |
| 	if data.Count() == 0 {
 | |
| 		r.data = data
 | |
| 		r.match = nil
 | |
| 	} else {
 | |
| 		//重新生成路由树
 | |
| 		m, err := parseData(data)
 | |
| 		if err != nil {
 | |
| 			// 路由树生成失败, 则放弃
 | |
| 			return r.data.Count()
 | |
| 		}
 | |
| 		// 路由树生成成功,则替换
 | |
| 		r.data = data
 | |
| 		r.match = m
 | |
| 	}
 | |
| 
 | |
| 	return r.data.Count()
 | |
| }
 | |
| 
 | |
| func parseData(data eosc.IUntyped) (IMatcher, error) {
 | |
| 	list := data.List()
 | |
| 	cs := make([]*Config, 0, len(list))
 | |
| 	for _, i := range list {
 | |
| 		cs = append(cs, i.(*Config))
 | |
| 	}
 | |
| 	return parse(cs)
 | |
| 
 | |
| }
 | 
