在此場景中,您建立了一個與 Instagram API 互動的 Go 命令列機器人。若要取得存取權杖,您需要啟動本機 HTTP 伺服器來擷取重新導向 URI。然而,您在檢索訪問令牌後嘗試手動關閉伺服器時遇到問題。
關閉伺服器時出現「伺服器已關閉」與「記憶體位址無效」錯誤伺服器
您遇到的錯誤表示HTTP伺服器在所有連線正常關閉之前被過早關閉。這可能是由於 HTTP 處理程序和伺服器關閉過程中的異步行所造成的。
考慮使用 context.WithCancel 建立一個可以取消的上下文當檢索到存取令牌時。將此上下文傳遞給 HTTP 處理程序,並在上下文關閉時使用 CancelFunc 正常關閉伺服器。
<code class="go">package main import ( "context" "io" "log" "net/http" ) func main() { ctx, cancel := context.WithCancel(context.Background()) http.HandleFunc("/quit", func(w http.ResponseWriter, r *http.Request) { io.WriteString(w, "Bye\n") cancel() }) http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { io.WriteString(w, "Hi\n") }) srv := &http.Server{Addr: ":8080"} go func() { err := srv.ListenAndServe() if err != http.ErrServerClosed { log.Println(err) } }() <-ctx.Done() err := srv.Shutdown(context.Background()) if err != nil { log.Println(err) } log.Println("done.") }</code>
您也可以使用跨多個HTTP 處理程序和主函數的相同上下文,以確保在伺服器應該關閉時通知所有函數。
<code class="go">package main import ( "context" "io" "log" "net/http" ) func main() { ctx, cancel := context.WithCancel(context.Background()) http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { io.WriteString(w, "Hi\n") }) http.HandleFunc("/quit", func(w http.ResponseWriter, r *http.Request) { io.WriteString(w, "Bye\n") cancel() }) srv := &http.Server{Addr: ":8080"} go func() { if err := srv.ListenAndServe(); err != nil { log.Printf("Httpserver: ListenAndServe() error: %s", err) } }() <-ctx.Done() if err := srv.Shutdown(ctx); err != nil && err != context.Canceled { log.Println(err) } log.Println("done.") }</code>
透過使用 context.WithCancel 或傳遞跨多個函數的相同上下文,您可以確保 HTTP 伺服器在所有連線關閉後正常關閉。這將防止您當前遇到的錯誤。
以上是回傳回應後如何優雅地關閉 Go HTTP 伺服器?的詳細內容。更多資訊請關注PHP中文網其他相關文章!