golang http client 使用gzip_Go实战--使用之gorilla/context
感慨:小说《人间失格》保温杯,枸杞中兴程序员跳楼朴树演到“情千缕,酒一杯,声声离笛催”时的哽咽《芳华》,芳华已逝,面目全非……哎,生活不易。生命不止,继续 go go go ~~~接下来打算跟大家分享一系列Gorilla web toolkit。gorilla是用golang写的web工具箱,里面提供了一系列的工具。在用golang开发web中,搭配gorilla可以加快整个开发的进程。官网:ht
感慨:
小说《人间失格》
保温杯,枸杞
中兴程序员跳楼
朴树演到“情千缕,酒一杯,声声离笛催”时的哽咽
《芳华》,芳华已逝,面目全非
……
哎,生活不易。
生命不止,继续 go go go ~~~
接下来打算跟大家分享一系列Gorilla web toolkit。
gorilla是用golang写的web工具箱,里面提供了一系列的工具。
在用golang开发web中,搭配gorilla可以加快整个开发的进程。
官网:
http://www.gorillatoolkit.org/
代码:
https://github.com/gorilla/
首先,介绍的是gorilla/context。
在Go1.7之前,Go标准库还没有内置Context。但是现在有了,所以通过标准库对比进行学习。
Package context
Package context defines the Context type, which carries deadlines, cancelation signals, and other request-scoped values across API boundaries and between processes.
Context 结构体
type Context interface { Deadline() (deadline time.Time, ok bool) Done()
Deadline(),返回截止时间和ok。
Done(),返回一个channel。当times out或者调用cancel方法时,将会close掉。
Err(),返回一个错误。该context为什么被取消掉。
Value(),返回值。
所有方法
func Background() Contextfunc TODO() Contextfunc WithCancel(parent Context) (ctx Context, cancel CancelFunc)func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc)func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)func WithValue(parent Context, key, val interface{}) Context1234567
context.TODO should be used context.TODO when it’s unclear which Context to use.
context.Background is typically used by the main function, initialization, and tests, and as the top-level Context for incoming requests.
Both are never canceled, have no values, and has no deadline.
WithCancel 对应的是 cancelCtx ,其中,返回一个 cancelCtx ,同时返回一个 CancelFunc,CancelFunc 是 context 包中定义的一个函数类型:type CancelFunc func()。调用这个 CancelFunc 时,关闭对应的c.done,也就是让他的后代goroutine退出
WithDeadline 和 WithTimeout 对应的是 timerCtx ,WithDeadline 和 WithTimeout 是相似的,WithDeadline 是设置具体的 deadline 时间,到达 deadline 的时候,后代 goroutine 退出,而 WithTimeout 简单粗暴,直接 return WithDeadline(parent, time.Now().Add(timeout))
WithValue 对应 valueCtx ,WithValue 是在 Context 中设置一个 map,拿到这个 Context 以及它的后代的 goroutine 都可以拿到 map 里的值
WithCancel使用示例
package mainimport ( "context" "fmt")func main() { gen := func(ctx context.Context)
输出:
1
2
3
4
5
WithDeadline使用示例
package mainimport ( "context" "fmt" "time")func main() { d := time.Now().Add(50 * time.Millisecond) ctx, cancel := context.WithDeadline(context.Background(), d) defer cancel() select { case
输出:
context deadline exceeded
WithTimeout使用示例
package mainimport ( "context" "fmt" "time")func main() { // Pass a context with a timeout to tell a blocking function that it // should abandon its work after the timeout elapses. ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond) defer cancel() select { case
输出:
context deadline exceeded
WithValue使用示例
package mainimport ( "context" "fmt")func main() { type favContextKey string f := func(ctx context.Context, k favContextKey) { if v := ctx.Value(k); v != nil { fmt.Println("found value:", v) return } fmt.Println("key not found:", k) } k := favContextKey("language") ctx := context.WithValue(context.Background(), k, "Go") f(ctx, k) f(ctx, favContextKey("color"))}1234567891011121314151617181920212223242526
输出:
found value: Go
key not found: color
HTTP请求中使用context
func Do(ctx context.Context, client *http.Client, req *http.Request)func Get(ctx context.Context, client *http.Client, url string)func Head(ctx context.Context, client *http.Client, url string)func PostForm(ctx context.Context, client *http.Client, url string, data url.Values)1234
说白了就是context作为函数的第一个参数:
package mainimport "fmt"import "context"// A message processes parameter and returns the result on responseChan.// ctx is places in a struct, but this is ok to do.type message struct { responseChan chan
输出:
The len of hi is 2
The len of hello is 5
遵循规则
遵循以下规则,以保持包之间的接口一致,并启用静态分析工具以检查上下文传播。
不要将 Contexts 放入结构体,相反context应该作为第一个参数传入,命名为ctx。 func DoSomething(ctx context.Context,arg Arg)error { // … use ctx … }
即使函数允许,也不要传入nil的 Context。如果不知道用哪种 Context,可以使用context.TODO()。
使用context的Value相关方法只应该用于在程序和接口中传递的和请求相关的元数据,不要用它来传递一些可选的参数
相同的 Context 可以传递给在不同的goroutine;Context 是并发安全的
gorilla/context
获取:
go get github.com/gorilla/context1
API
++func Clear(r *http.Request)++
Clear removes all values stored for a given request.
This is usually called by a handler wrapper to clean up request variables at the end of a request lifetime. See ClearHandler().
++func ClearHandler(h http.Handler) http.Handler++
ClearHandler wraps an http.Handler and clears request values at the end of a request lifetime.
++func Delete(r *http.Request, key interface{})++
Delete removes a value stored for a given key in a given request.
++func Get(r *http.Request, key interface{}) interface{}++
Get returns a value stored for a given key in a given request.
++func GetAll(r *http.Request) map[interface{}]interface{}++
GetAll returns all stored values for the request as a map. Nil is returned for invalid requests.
++func GetAllOk(r *http.Request) (map[interface{}]interface{}, bool)++
GetAllOk returns all stored values for the request as a map and a boolean value that indicates if the request was registered.
++func GetOk(r *http.Request, key interface{}) (interface{}, bool)++
GetOk returns stored value and presence state like multi-value return of map access.
++func Purge(maxAge int) int++
Purge removes request data stored for longer than maxAge, in seconds. It returns the amount of requests removed.
If maxAge <= 0, all request data is removed.
This is only used for sanity check: in case context cleaning was not properly set some request data can be kept forever, consuming an increasing amount of memory. In case this is detected, Purge() must be called periodically until the problem is fixed.
++func Set(r *http.Request, key, val interface{})++
Set stores a value for a given key in a given request.
示例:
type contextString stringconst ConfigKey contextString = "context"func SetConfigHandler(w http.ResponseWriter, r *http.Request) { var config Config //...Getting the config data from request... context.Set(r, ConfigKey, config) }func GetClicksHandler(w http.ResponseWriter, r *http.Request) { config := context.Get(r, ConfigKey).(Config) if config.TrackClicks{ WriteNumberClicks(w) }}12345678910111213141516
存取值
package mainimport ( "net/http" "strconv" "github.com/gorilla/context")func main() { http.Handle("/", http.HandlerFunc(myHander)) http.ListenAndServe(":8080", nil)}func myHander(rw http.ResponseWriter, r *http.Request) { context.Set(r, "user", "SuperWang") context.Set(r, "age", 66) doHander(rw, r)}func doHander(rw http.ResponseWriter, r *http.Request) { user := context.Get(r, "user").(string) age := context.Get(r, "age").(int) rw.WriteHeader(http.StatusOK) rw.Write([]byte("the user is " + user + ", age is " + strconv.Itoa(age)))}123456789101112131415161718192021222324252627
gorilla/mux与gorilla/context结合使用
package main import ( "fmt" "github.com/gorilla/context" "github.com/gorilla/mux" "net/http" ) type Key string const GlobalRequestVariable Key = "" func SetGlobalHandler(w http.ResponseWriter, r *http.Request) { context.Set(r, GlobalRequestVariable, "test") get, ok := context.GetOk(r, GlobalRequestVariable) w.Write([]byte(fmt.Sprintf("GetOK : [%v] and get what :[%v] ", ok, get))) InternalGetGlobalHandler(w, r) } func InternalGetGlobalHandler(w http.ResponseWriter, r *http.Request) { get, ok := context.GetOk(r, GlobalRequestVariable) w.Write([]byte(fmt.Sprintf("Internal GetOK : [%v] and get what :[%v] ", ok, get))) } func GetGlobalHandler(w http.ResponseWriter, r *http.Request) { get, ok := context.GetOk(r, GlobalRequestVariable) w.Write([]byte(fmt.Sprintf("GetOK : [%v] and get what :[%v] ", ok, get))) } func main() { mx := mux.NewRouter() mx.HandleFunc("/", SetGlobalHandler) mx.HandleFunc("/get", GetGlobalHandler) http.ListenAndServe(":8080", mx) }
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)