Skip to content

Commit 034fe1e

Browse files
committed
恢复共用一个实例
1 parent ee09d7b commit 034fe1e

File tree

2 files changed

+96
-52
lines changed

2 files changed

+96
-52
lines changed

http/server/handler.go

Lines changed: 90 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,25 @@ var (
2020
server = newHTTPServer()
2121
)
2222

23-
type uriRegexp struct {
24-
path string
25-
keys []string
26-
exp *regexp.Regexp
27-
source reflect.Type
23+
type handlerRegexp struct {
24+
keys []string
25+
exp *regexp.Regexp
26+
handler
2827
}
2928

30-
// iface 对外服务接口, path格式:Method/URI
31-
type iface struct {
32-
path string
33-
source reflect.Type
29+
// handler 对外服务接口, path格式:Method/URI
30+
type handler struct {
31+
path string
32+
call func(http.ResponseWriter, *http.Request)
3433
}
3534

3635
type prefix struct {
37-
path string
38-
uriExps []uriRegexp
36+
path string
37+
exps []handlerRegexp
3938
}
4039

4140
type httpServer struct {
42-
path map[string]iface
41+
path map[string]handler
4342
prefix *btree.BTree
4443
filter Filter
4544
listener net.Listener
@@ -48,7 +47,7 @@ type httpServer struct {
4847

4948
func newHTTPServer() *httpServer {
5049
return &httpServer{
51-
path: make(map[string]iface),
50+
path: make(map[string]handler),
5251
prefix: btree.New(3),
5352
filter: defaultFilter,
5453
}
@@ -83,6 +82,32 @@ func Register(obj interface{}) error {
8382
return register(obj, "", false)
8483
}
8584

85+
//RegisterPath 注册url完全匹配.
86+
func RegisterPath(obj interface{}, path string) error {
87+
return register(obj, path, false)
88+
}
89+
90+
//RegisterHandler 注册自定义url完全匹配.
91+
func RegisterHandler(call func(http.ResponseWriter, *http.Request), method, path string) error {
92+
h := handler{
93+
path: fmt.Sprintf("%v%v", method, path),
94+
call: call,
95+
}
96+
97+
server.Lock()
98+
defer server.Unlock()
99+
100+
if _, ok := server.path[h.path]; ok {
101+
return errors.Errorf("exist url:%v %v", method, path)
102+
}
103+
104+
server.path[h.path] = h
105+
106+
log.Infof("add handler %v %v", method, path)
107+
108+
return nil
109+
}
110+
86111
//RegisterPrefix 注册url前缀.
87112
func RegisterPrefix(obj interface{}, path string) error {
88113
return register(obj, path, true)
@@ -100,28 +125,22 @@ func init() {
100125
keysExp = exp
101126
}
102127

103-
func newURIRegexp(path string, source reflect.Type) uriRegexp {
104-
ur := uriRegexp{
105-
path: path,
106-
source: source,
107-
}
128+
func newHandlerRegexp(h handler) handlerRegexp {
129+
hr := handlerRegexp{handler: h}
108130

109-
//log.Debugf("path:%v", path)
110-
for _, m := range keysExp.FindAllStringSubmatch(path, -1) {
111-
//log.Debugf("path:%v, key:%#v", path, m)
112-
ur.keys = append(ur.keys, m[1])
131+
for _, m := range keysExp.FindAllStringSubmatch(hr.path, -1) {
132+
hr.keys = append(hr.keys, m[1])
113133
}
114134

115-
np := keysExp.ReplaceAllString(path, "(.+)")
135+
np := keysExp.ReplaceAllString(hr.path, "(.+)")
116136
exp, err := regexp.Compile(np)
117137
if err != nil {
118138
panic(err.Error())
119139
}
120-
ur.exp = exp
121140

122-
// log.Debugf("uriRegexp:%#v", ur)
141+
hr.exp = exp
123142

124-
return ur
143+
return hr
125144
}
126145

127146
func register(obj interface{}, path string, isPrefix bool) error {
@@ -146,15 +165,26 @@ func register(obj interface{}, path string, isPrefix bool) error {
146165
method := rt.Method(i).Name
147166
//log.Debugf("rt:%v, %d, method:%v", rt, i, method)
148167
switch method {
149-
case POST.String():
150-
case GET.String():
151-
case PUT.String():
152-
case DELETE.String():
168+
case http.MethodPost:
169+
case http.MethodGet:
170+
case http.MethodPut:
171+
case http.MethodDelete:
153172
default:
154-
log.Warnf("ignore %v %v %v", method, path, rt)
173+
log.Warnf("ignore func:%v %v %v", method, path, rt)
155174
continue
156175
}
157176

177+
mt := rv.MethodByName(method)
178+
if mt.Type().NumIn() != 2 || mt.Type().In(0).String() != "http.ResponseWriter" || mt.Type().In(1).String() != "*http.Request" {
179+
log.Debugf("ignore func:%v %v %v", method, path, mt.Type())
180+
continue
181+
}
182+
183+
h := handler{
184+
path: fmt.Sprintf("%v%v", method, path),
185+
call: mt.Interface().(func(http.ResponseWriter, *http.Request)),
186+
}
187+
158188
//前缀匹配
159189
if isPrefix {
160190
p := prefix{
@@ -166,32 +196,26 @@ func register(obj interface{}, path string, isPrefix bool) error {
166196
}
167197

168198
// log.Debugf("path:%v", p.path)
169-
170199
if server.prefix.Has(&p) {
171200
p = *(server.prefix.Get(&p).(*prefix))
172201
}
173202

174-
exp := newURIRegexp(path, rt.Elem())
203+
exp := newHandlerRegexp(h)
175204

176-
p.uriExps = append(p.uriExps, exp)
205+
p.exps = append(p.exps, exp)
177206

178207
server.prefix.ReplaceOrInsert(&p)
179208

180209
log.Infof("add prefix %v %v %v %v", method, exp.path, exp.keys, rt)
181-
182210
continue
183211
}
184212

185-
ifc := iface{
186-
path: fmt.Sprintf("%v%v", method, path),
187-
source: rt.Elem(),
188-
}
189213
//全路径匹配
190-
if _, ok := server.path[ifc.path]; ok {
191-
panic(fmt.Sprintf("exist url:%v %v", method, path))
214+
if _, ok := server.path[h.path]; ok {
215+
return errors.Errorf("exist url:%v %v", method, path)
192216
}
193217

194-
server.path[ifc.path] = ifc
218+
server.path[h.path] = h
195219
log.Infof("add path %v %v %v", method, path, rt)
196220
}
197221

@@ -205,7 +229,7 @@ func AddFilter(filter Filter) {
205229
server.filter = filter
206230
}
207231

208-
func parseRequestValues(path string, ur uriRegexp) context.Context {
232+
func parseRequestValues(path string, ur handlerRegexp) context.Context {
209233
ctx := context.Background()
210234
for i, v := range ur.exp.FindAllStringSubmatch(path, -1) {
211235
//log.Debugf("i:%v, v:%#v, keys:%#v", i, v, ur.keys)
@@ -214,15 +238,15 @@ func parseRequestValues(path string, ur uriRegexp) context.Context {
214238
return ctx
215239
}
216240

217-
func getInterface(method, path string) (reflect.Type, context.Context) {
241+
func getHandler(method, path string) (func(http.ResponseWriter, *http.Request), context.Context) {
218242
server.RLock()
219243
defer server.RUnlock()
220244

221245
path = method + path
222246

223247
if i, ok := server.path[path]; ok {
224248
//log.Debugf("find path:%v", path)
225-
return i.source, nil
249+
return i.call, nil
226250
}
227251

228252
var p prefix
@@ -235,12 +259,20 @@ func getInterface(method, path string) (reflect.Type, context.Context) {
235259
return !ok
236260
})
237261

238-
for _, ue := range p.uriExps {
262+
if !ok {
263+
return nil, nil
264+
}
265+
266+
for _, ue := range p.exps {
239267
if ue.exp.MatchString(path) {
268+
if len(ue.keys) == 0 {
269+
return ue.call, nil
270+
}
240271
// log.Debugf("uri exp:%v, path:%v", ue, path)
241-
return ue.source, parseRequestValues(path, ue)
272+
return ue.call, parseRequestValues(path, ue)
242273
}
243274
}
275+
244276
return nil, nil
245277
}
246278

@@ -260,8 +292,8 @@ func (s *httpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
260292
return
261293
}
262294

263-
tp, ctx := getInterface(r.Method, r.URL.Path)
264-
if tp == nil {
295+
h, ctx := getHandler(r.Method, r.URL.Path)
296+
if h == nil {
265297
log.Errorf("%v %v %v not found.", r.RemoteAddr, r.Method, r.URL)
266298
SendResponse(w, http.StatusNotFound, "invalid request")
267299
return
@@ -271,10 +303,9 @@ func (s *httpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
271303
nr = nr.WithContext(ctx)
272304
}
273305

274-
log.Debugf("%v %v %v %v", r.RemoteAddr, r.Method, r.URL, tp)
306+
log.Debugf("%v %v %v %v", r.RemoteAddr, r.Method, r.URL, h)
275307

276-
callback := reflect.New(tp).MethodByName(r.Method).Interface().(func(http.ResponseWriter, *http.Request))
277-
callback(w, nr)
308+
h(w, nr)
278309

279310
return
280311
}
@@ -297,6 +328,13 @@ func Start(addr string) error {
297328
return http.Serve(ln, server)
298329
}
299330

331+
//Listener 获取监听地址.
332+
func Listener() net.Listener {
333+
server.Lock()
334+
defer server.Unlock()
335+
return server.listener
336+
}
337+
300338
//Stop 停止httpServer监听, 进行中的任务并不会因此而停止.
301339
func Stop() error {
302340
server.Lock()

main.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,19 @@ func testHTTPClient() {
3636
fmt.Printf("response:%s\n", buf)
3737
}
3838

39+
func testHandler(w http.ResponseWriter, req *http.Request) {
40+
fmt.Fprintf(w, "testHandler:%v", req.RemoteAddr)
41+
}
42+
3943
func main() {
4044
addr := flag.String("h", ":9000", "api listen address")
4145
flag.Parse()
4246

4347
server.Register(&index{})
4448
server.RegisterPrefix(&regexpTest{}, "/regexp/{user}/test/")
4549

50+
server.RegisterHandler(testHandler, "GET", "/testHandler/")
51+
4652
go func() {
4753
for i := 0; i < 5; i++ {
4854
time.Sleep(time.Second)

0 commit comments

Comments
 (0)