Go 为什么我无法在服务器端获取上下文值
我想使用函数contextWithValue中的上下文从客户端发送值Go 为什么我无法在服务器端获取上下文值,go,Go,我想使用函数contextWithValue中的上下文从客户端发送值 func contextWithValue(key int, url string) { req, err := http.NewRequestWithContext(contextLogger.SetValueX(context.Background()), "get", url, nil) client := http.Client{}
func contextWithValue(key int, url string) {
req, err := http.NewRequestWithContext(contextLogger.SetValueX(context.Background()), "get", url, nil)
client := http.Client{}
resp, _ := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println("Response status:", resp.Status)
scanner := bufio.NewScanner(resp.Body)
for i := 0; scanner.Scan(); i++ {
fmt.Println(scanner.Text())
}
if err := scanner.Err(); err != nil {
panic(err)
}
}
但是在服务器端,我无法使用Println函数从上下文中获取值
func Println(ctx context.Context, msg string) {
id := ctx.Value(RequestId)
if id == nil {
log.Println("Could not find value")
return
}
log.Printf("%d %s", id.(int64), msg)
}
这里出了什么问题?
上下文并不像其他人所说的那样是HTTP的一部分。从http协议中可以看出:
对于传出的客户端请求,上下文控制取消
对于传入的服务器请求,当客户端的连接关闭、请求被取消(使用HTTP/2)或ServeHTTP方法返回时,上下文被取消
因此,http客户机-服务器通信中的上下文仅用于控制计算。对于客户端来说,无论请求是否从服务器端成功,都可以由于超时或上下文的cancel方法调用而终止请求。对于服务器,它将侦听客户端终止/关闭连接,或者指定服务器超时,或者在上下文超时时停止进程
不能通过上下文传递值,因为上下文的创建只发生在客户端和服务器的每一侧。如果要传递值,唯一的方法是为它们创建头。上下文不是请求的一部分。Go的上下文对象与HTTP无关。它更常用于在服务器端的中间件之间传递值。因此,如果你想利用这种价值传递机制,你可以把你的价值放在客户端请求中,让服务器端中间件提取该价值并更新服务器端上下文。你可能会把上下文和。上下文确实允许通过所有goroutine传递状态,这些goroutine的工作逻辑上属于处理特定的客户机请求,但是上下文从来没有并且在任何情况下以某种方式“自动”填充客户机提供的web表单(并且不能明智地做到这一点)。