在下面的程式中,我有兩個路由器。一個是在localhost:3000公共接入點作業并充當公共接入點。它還可以將帶有資料的請求發送到localhost:8000正在處理資料的另一個本地地址。第二個路由器正在作業localhost:8000并處理第一個路由器的處理請求。
問題
第一個路由器向第二個使用http.NewRequestWithContext()函式發送帶有背景關系的請求。正在將值添加到背景關系中,并將背景關系添加到請求中。當請求到達第二個路由器時,它沒有先前添加的值。
一些諸如錯誤處理之類的東西沒有被寫成不在這里發布代碼墻。
package main
import (
"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
}
resp, err := http.DefaultClient.Do(postReq) // running actual request
// pls, proceed to Solver()
// do stuff to resp
// also despite arriving to middleware without right context
// here resp contains a request with correct context
})
return r
}
func Solver(next http.Handler) http.Handler { // here we end up after sending postReq
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
if r.Context().Value("str").(string) == "" {
return // the request arrive without "str" in its context
}
ctxWithResult := context.WithValue(r.Context(), "result", mockFunc(r.Context()))
next.ServeHTTP(rw, r.Clone(ctxWithResult))
})
}
func InternalService() http.Handler {
r := chi.NewRouter()
r.Use(middleware.Logger)
r.With(Solver).Post("/tasks/solution", emptyHandlerFunc)
return r
}
uj5u.com熱心網友回復:
你對背景關系的理解是不正確的。
背景關系(在一定程度上簡化并參考NewRequestWithContextAPI)只是一個記憶體中物件,您可以使用它來控制請求的生命周期(處理/觸發取消)。
但是,您的代碼正在進行 HTTP 呼叫,該呼叫使用 HTTP 協議通過線路(編組)。該協議不了解 golang 的背景關系或其值。在您的場景中,/tasks/str和/tasks/solution都在同一臺服務器上運行。如果它們在不同的服務器上,可能還有不同的語言和應用程式服務器,那么背景關系不能被發送。
由于 API 位于同一服務器中,也許您可??以避免進行完整的 HTTP 呼叫并直接呼叫 API/方法。它也可能變得更快。
如果您仍想從背景關系發送其他值,則必須使用其他屬性(如 HTTP 標頭、引數、正文)來發送所需的資訊。這可以提供有關如何通過 HTTP 從背景關系序列化資料的更多資訊。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/348269.html
上一篇:使用Makefile創建兩個輸出
