forked from aceld/zinx
-
Notifications
You must be signed in to change notification settings - Fork 0
/
router.go
116 lines (95 loc) · 4.03 KB
/
router.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package znet
import (
"strconv"
"sync"
"github.com/aceld/zinx/ziface"
)
// BaseRouter is used as the base class when implementing a router.
// Depending on the needs, the methods of this base class can be overridden.
// (实现router时,先嵌入这个基类,然后根据需要对这个基类的方法进行重写)
type BaseRouter struct{}
// Here, all of BaseRouter's methods are empty, because some routers may not want to have PreHandle or PostHandle.
// Therefore, inheriting all routers from BaseRouter has the advantage that PreHandle and PostHandle do not need to be
// implemented to instantiate a router.
// (这里之所以BaseRouter的方法都为空,
// 是因为有的Router不希望有PreHandle或PostHandle
// 所以Router全部继承BaseRouter的好处是,不需要实现PreHandle和PostHandle也可以实例化)
// PreHandle -
func (br *BaseRouter) PreHandle(req ziface.IRequest) {}
// Handle -
func (br *BaseRouter) Handle(req ziface.IRequest) {}
// PostHandle -
func (br *BaseRouter) PostHandle(req ziface.IRequest) {}
// New slice-based router
// The new version of the router has basic logic that allows users to pass in varying numbers of router handlers.
// The router will save all of these router handler functions and find them when a request comes in, then execute them using IRequest.
// The router can set globally shared components using the Use method.
// The router can be grouped using Group, and groups also have their own Use method for setting group-shared components.
// (新切片集合式路由
// 新版本路由基本逻辑,用户可以传入不等数量的路由路由处理器
// 路由本体会讲这些路由处理器函数全部保存,在请求来的时候找到,并交由IRequest去执行
// 路由可以设置全局的共用组件通过Use方法
// 路由可以分组,通过Group,分组也有自己对应Use方法设置组共有组件)
type RouterSlices struct {
Apis map[uint32][]ziface.RouterHandler
Handlers []ziface.RouterHandler
sync.RWMutex
}
func NewRouterSlices() *RouterSlices {
return &RouterSlices{
Apis: make(map[uint32][]ziface.RouterHandler, 10),
Handlers: make([]ziface.RouterHandler, 0, 6),
}
}
func (r *RouterSlices) Use(handles ...ziface.RouterHandler) {
r.Handlers = append(r.Handlers, handles...)
}
func (r *RouterSlices) AddHandler(msgId uint32, Handlers ...ziface.RouterHandler) {
// 1. Check if the API handler method bound to the current msg already exists
if _, ok := r.Apis[msgId]; ok {
panic("repeated api , msgId = " + strconv.Itoa(int(msgId)))
}
finalSize := len(r.Handlers) + len(Handlers)
mergedHandlers := make([]ziface.RouterHandler, finalSize)
copy(mergedHandlers, r.Handlers)
copy(mergedHandlers[len(r.Handlers):], Handlers)
r.Apis[msgId] = append(r.Apis[msgId], mergedHandlers...)
}
func (r *RouterSlices) GetHandlers(MsgId uint32) ([]ziface.RouterHandler, bool) {
r.RLock()
defer r.RUnlock()
handlers, ok := r.Apis[MsgId]
return handlers, ok
}
func (r *RouterSlices) Group(start, end uint32, Handlers ...ziface.RouterHandler) ziface.IGroupRouterSlices {
return NewGroup(start, end, r, Handlers...)
}
type GroupRouter struct {
start uint32
end uint32
Handlers []ziface.RouterHandler
router ziface.IRouterSlices
}
func NewGroup(start, end uint32, router *RouterSlices, Handlers ...ziface.RouterHandler) *GroupRouter {
g := &GroupRouter{
start: start,
end: end,
Handlers: make([]ziface.RouterHandler, 0, len(Handlers)),
router: router,
}
g.Handlers = append(g.Handlers, Handlers...)
return g
}
func (g *GroupRouter) Use(Handlers ...ziface.RouterHandler) {
g.Handlers = append(g.Handlers, Handlers...)
}
func (g *GroupRouter) AddHandler(MsgId uint32, Handlers ...ziface.RouterHandler) {
if MsgId < g.start || MsgId > g.end {
panic("add router to group err in msgId:" + strconv.Itoa(int(MsgId)))
}
finalSize := len(g.Handlers) + len(Handlers)
mergedHandlers := make([]ziface.RouterHandler, finalSize)
copy(mergedHandlers, g.Handlers)
copy(mergedHandlers[len(g.Handlers):], Handlers)
g.router.AddHandler(MsgId, mergedHandlers...)
}