context 提供在不同的Handler 或Middleware 共享变量的功能,即通常所说的上下文。
gorilla/context 是一个很好的库:
1
2
3
4
5
6
7
8
9
10
11
12
13
// 先定义
var (
mutex sync.RWMutex
data = make(map[*http.Request]map[interface{}]interface{})
)
func myHandler(w http.ResponseWriter, r *http.Request) {
context.Set(r, "foo", "bar")
}
func myOtherHandler(w http.ResponseWriter, r *http.Request) {
val := context.Get(r, "foo").(string)
}
goji 在他自身的框架里也有实现,使用更方便 web.C :
1
2
3
4
5
6
7
8
9
10
11
12
func myMiddleware(c *web.C, h http.Handler) http.Handler {
fn := func (w http.ResponseWriter, r *http.Request) {
c.Env["name"] = "world"
h.ServeHTTP(w, r)
}
return http.HandlerFunc(fn)
}
func hello(c web.C, w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %s!", c.Env["name"].(string))
}
更新
上面是很早的解决方案, 自从 Go 1.7
后,就可以使用标准库 http.Request.Context()
来处理上下文。
在 go1.7 之前,context 还是非编制的,存在(golang.org/x/net/context
)中,golang 团队发现 context 这个东西很好用,于是把它收编了,1.7 版本正式进入了标准库。专门用来简化处理多个goroutine之间与请求域的数据、取消信号、截止时间等相关操作。
对服务器传入的请求应该创建上下文,而对服务器的传出调用应该接受上下文,它们之间的函数调用链必须传递上下文,或者可以使用 WithCancel
、WithDeadline
、WithTimeOut
、WithValue
创建的派生上下文,当一个上下文被取消时,它派生的所有上下文也被取消。
跟 web 上下文关系大的 参见 https://golang.google.cn/pkg/net/http/#Request.WithContext
本文网址: https://golangnote.com/topic/52.html 转摘请注明来源