github.com/chanxuehong/wechat@v0.0.0-20230222024006-36f0325263cd/mch/core/context.go (about) 1 package core 2 3 import ( 4 "net/http" 5 6 "github.com/chanxuehong/util" 7 ) 8 9 const ( 10 initHandlerIndex = -1 11 abortHandlerIndex = maxHandlerChainSize 12 ) 13 14 // Context 是 Handler 处理消息(事件)的上下文环境. 非并发安全! 15 type Context struct { 16 Server *Server 17 18 ResponseWriter http.ResponseWriter 19 Request *http.Request 20 21 RequestBody []byte // 回调请求的 http-body, 就是消息体的原始内容, 记录log可能需要这个信息 22 Msg map[string]string // 请求消息, return_code == "SUCCESS" && result_code == "SUCCESS" 23 24 handlers HandlerChain 25 handlerIndex int 26 27 kvs map[string]interface{} 28 } 29 30 // IsAborted 返回 true 如果 Context.Abort() 被调用了, 否则返回 false. 31 func (ctx *Context) IsAborted() bool { 32 return ctx.handlerIndex >= abortHandlerIndex 33 } 34 35 // Abort 阻止系统调用当前 handler 后续的 handlers, 即当前的 handler 处理完毕就返回, 一般在 middleware 中调用. 36 func (ctx *Context) Abort() { 37 ctx.handlerIndex = abortHandlerIndex 38 } 39 40 // Next 中断当前 handler 程序逻辑执行其后续的 handlers, 一般在 middleware 中调用. 41 func (ctx *Context) Next() { 42 for { 43 ctx.handlerIndex++ 44 if ctx.handlerIndex >= len(ctx.handlers) { 45 ctx.handlerIndex-- 46 break 47 } 48 handler := ctx.handlers[ctx.handlerIndex] 49 if handler != nil { 50 handler.ServeMsg(ctx) 51 } 52 } 53 } 54 55 // SetHandlers 设置 handlers 给 Context.Next() 调用, 务必在 Context.Next() 调用之前设置, 否则会 panic. 56 // 57 // NOTE: 此方法一般用不到, 除非你自己实现一个 Handler 给 Server 使用, 参考 HandlerChain. 58 func (ctx *Context) SetHandlers(handlers HandlerChain) { 59 if len(handlers) > maxHandlerChainSize { 60 panic("too many handlers") 61 } 62 for _, h := range handlers { 63 if h == nil { 64 panic("handler can not be nil") 65 } 66 } 67 if ctx.handlerIndex != initHandlerIndex { 68 panic("can't set handlers after Context.Next() called") 69 } 70 ctx.handlers = handlers 71 } 72 73 // Response 回复消息给微信服务器 74 func (ctx *Context) Response(msg map[string]string) (err error) { 75 return util.EncodeXMLFromMap(ctx.ResponseWriter, msg, "xml") 76 } 77 78 // Set 存储 key-value pair 到 Context 中. 79 func (ctx *Context) Set(key string, value interface{}) { 80 if ctx.kvs == nil { 81 ctx.kvs = make(map[string]interface{}) 82 } 83 ctx.kvs[key] = value 84 } 85 86 // Get 返回 Context 中 key 对应的 value, 如果 key 存在的返回 (value, true), 否则返回 (nil, false). 87 func (ctx *Context) Get(key string) (value interface{}, exists bool) { 88 value, exists = ctx.kvs[key] 89 return 90 } 91 92 // MustGet 返回 Context 中 key 对应的 value, 如果 key 不存在则会 panic. 93 func (ctx *Context) MustGet(key string) interface{} { 94 if value, exists := ctx.Get(key); exists { 95 return value 96 } 97 panic(`[kvs] key "` + key + `" does not exist`) 98 }