为了账号安全,请及时绑定邮箱和手机立即绑定

使用 http.NewRequestWithContext() 创建的请求在传递给中间件时会丢失

使用 http.NewRequestWithContext() 创建的请求在传递给中间件时会丢失

Go
冉冉说 2022-10-10 19:12:22
在下面的程序中,我有两个路由器。一个在公共接入点工作localhost:3000并充当公共接入点。它还可以将带有数据的请求发送到另一个localhost:8000正在处理数据的本地地址。第二个路由器正在localhost:8000处理第一个路由器的处理请求。问题http.NewRequestWithContext()第一个路由器向第二个使用函数发送带有上下文的请求。该值被添加到上下文中,并且上下文被添加到请求中。当请求到达第二个路由器时,它没有先前添加的值。诸如错误处理之类的某些内容并未被编写为不要在此处发布代码墙。package mainimport (    "bytes"    "context"    "net/http"    "github.com/go-chi/chi"    "github.com/go-chi/chi/middleware")func main() {    go func() {        err := http.ListenAndServe(            "localhost:3000",            GetDataAndSolve(),        )        if err != nil {            panic(err)        }    }()    go func() {        err := http.ListenAndServe( // in GetDataAndSolve() we send requests            "localhost:8000", // with data for processing            InternalService(),        )        if err != nil {            panic(err)        }    }()    // interrupt := make(chan os.Signal, 1)     // signal.Notify(interrupt, syscall.SIGTERM, syscall.SIGINT)    // <-interrupt // just a cool way to close the program, uncomment if you need it}func GetDataAndSolve() http.Handler {    r := chi.NewRouter()    r.Use(middleware.Logger)    r.Get("/tasks/str", func(rw http.ResponseWriter, r *http.Request) {        // receiving data for processing...        taskCtx := context.WithValue(r.Context(), "str", "strVar") // the value is being        postReq, err := http.NewRequestWithContext(                // stored to context            taskCtx, // context is being given to request            "POST",            "http://localhost:8000/tasks/solution",            bytes.NewBuffer([]byte("something")),        )        postReq.Header.Set("Content-Type", "application/json") // specifying for endpoint        if err != nil {                                        // what we are sending            return        }}
查看完整描述

1 回答

?
素胚勾勒不出你

TA贡献1827条经验 获得超9个赞

您对上下文的理解不正确。

上下文(在某种程度上简化并参考NewRequestWithContextAPI)只是一个内存中的对象,您可以使用它来控制请求的生命周期(处理/触发取消)。

但是,您的代码正在进行 HTTP 调用,该调用使用 HTTP 协议通过线路(编组)。该协议不理解 golang 的上下文或其值。在您的场景中,两者/tasks/str/tasks/solution在同一台服务器上运行。如果它们位于不同的服务器上怎么办,可能还有不同的语言和应用程序服务器,所以上下文不能被发送。

由于 API 在同一台服务器中,也许您可以避免进行完整的 HTTP 调用,而直接调用 API/方法。它也可能会变得更快。

如果您仍想从上下文发送附加值,那么您将不得不利用其他属性(如 HTTP 标头、参数、正文)来发送所需的信息。这可以提供有关如何通过 HTTP 从上下文序列化数据的更多信息。


查看完整回答
反对 回复 2022-10-10
  • 1 回答
  • 0 关注
  • 332 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号