Go 为什么我无法在服务器端获取上下文值

Go 为什么我无法在服务器端获取上下文值,go,Go,我想使用函数contextWithValue中的上下文从客户端发送值 func contextWithValue(key int, url string) { req, err := http.NewRequestWithContext(contextLogger.SetValueX(context.Background()), "get", url, nil) client := http.Client{}

我想使用函数contextWithValue中的上下文从客户端发送值

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表单(并且不能明智地做到这一点)。