帶Body 的HTTP 請求中的上下文取消信號丟失
在Go 中開發HTTP 伺服器時,出現了一個問題: context. Done( ) 通道無法捕獲帶有正文的請求的客戶端斷開連接訊號。此行為與 GET 請求不同,後者成功偵測到客戶端離開。
根本原因
這種不一致源自於 net/http 伺服器的功能。它的連接檢查機制僅在應用程式讀取請求正文時啟動。由於 GET 請求沒有正文,因此連線檢查會立即觸發,使伺服器能夠及時偵測用戶端取消。但是,對於 POST 請求,伺服器會等到讀取內文後才開始連線檢查。
解決方案
要解決此問題,需要手動讀取請求正文刺激伺服器的連線檢查過程。下面的程式碼片段演示了這一點:
func handler(w http.ResponseWriter, r *http.Request) { go func(done <-chan struct{}) { <-done fmt.Println("message", "client connection has gone away, request got cancelled") }(r.Context().Done()) io.Copy(ioutil.Discard, r.Body) // Read the body time.Sleep(30 * time.Second) fmt.Fprintf(w, "Hi there, I love %s!\n", r.URL.Path[1:]) }
透過明確讀取請求正文,伺服器可以及時檢測客戶端斷開連接,即使對於帶有正文的請求也是如此。這允許在伺服器端進行適當的清理和資源釋放。
以上是為什麼 HTTP POST 請求會錯過 Go 中的上下文取消訊號?的詳細內容。更多資訊請關注PHP中文網其他相關文章!