首頁  >  文章  >  後端開發  >  如何在回應後正常關閉 HTTP 伺服器?

如何在回應後正常關閉 HTTP 伺服器?

Linda Hamilton
Linda Hamilton原創
2024-10-31 04:19:30579瀏覽

How to Gracefully Shut Down an HTTP Server After a Response?

回應後正常關閉HTTP 伺服器

問題

使用本地HTTP 伺服器擷取OAuth 存取權杖以進行Instagram API 整合時,向使用者顯示令牌後需要關閉伺服器。但是,嘗試使用srv.Shutdown() 手動終止伺服器會導致錯誤:

Httpserver: ListenAndServe() error: http: Server closed
http: panic serving [::1]:61793: runtime error: invalid memory address or nil pointer dereference

分析

發生錯誤是因為在showTokenToUser 期間HTTP 伺服器仍在處理其他請求handler 正在嘗試將其關閉。

解決方案

完成回呼請求後優雅地關閉HTTP 伺服器:

1.使用Context.WithCancel()

使用context.WithCancel() 建立可以手動取消的上下文。啟動時將此上下文傳遞給 HTTP 伺服器。

2.優雅地關閉伺服器

在回調處理程序showTokenToUser中,呼叫srv.Shutdown(ctx)來優雅地關閉伺服器。 ctx 是傳遞給伺服器的已取消上下文。

程式碼
<code class="go">package main

import (
    "context"
    "io"
    "log"
    "net/http"
)

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    http.HandleFunc("/instagram/callback", func(w http.ResponseWriter, r *http.Request) {
        showTokenToUser(w, r, ctx)
    })

    srv := &http.Server{Addr: ":8000"}
    go func() {
        if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
            log.Printf("httpserver: ListenAndServe() error: %s", err)
        }
    }()

    <-ctx.Done()

    // Gracefully shut down the server
    if err := srv.Shutdown(context.Background()); err != nil && err != context.Canceled {
        log.Println(err)
    }
}

func showTokenToUser(w http.ResponseWriter, r *http.Request, ctx context.Context) {
    io.WriteString(w, fmt.Sprintf("Your access token is: %v", r.URL.Query().Get("code")))
    cancel()
}</code>

此解決方案可確保 HTTP 伺服器在回呼請求完成後正常關閉,不會導致任何錯誤或中斷持續連線。

以上是如何在回應後正常關閉 HTTP 伺服器?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn