本指南解決了Go 的HTTP 回應處理中的緩衝問題,其中回應通常被緩衝並以區塊的形式傳送到處理請求後的客戶端。對於串流場景,這可能並不理想。
提供的程式碼片段說明了問題,其中兩行資料應該被串流傳輸,但由於緩衝而同時發送。
解決此問題的一種方法是明確刷新回應緩衝區。 Go 的 ResponseWriter 提供了 Flush 方法,但其可用性取決於實作。
例如,以下修改後的程式碼包含刷新:
func handle(res http.ResponseWriter, req *http.Request) { fmt.Fprintf(res, "sending first line of data") if f, ok := res.(http.Flusher); ok { f.Flush() } sleep(10) //not real code fmt.Fprintf(res, "sending second line of data") }
在某些場景下,例如串流外部命令的輸出,直接傳輸外部命令的輸出,直接刷新可能不夠。 Go 的管道機制允許在命令的輸出和響應編寫器之間進行直接串流傳輸。
這是一個範例實作:
pipeReader, pipeWriter := io.Pipe() cmd.Stdout = pipeWriter cmd.Stderr = pipeWriter go writeCmdOutput(res, pipeReader) err := cmd.Run() pipeWriter.Close() func writeCmdOutput(res http.ResponseWriter, pipeReader *io.PipeReader) { buffer := make([]byte, BUF_LEN) for { n, err := pipeReader.Read(buffer) if err != nil { pipeReader.Close() break } data := buffer[0:n] res.Write(data) if f, ok := res.(http.Flusher); ok { f.Flush() } //reset buffer for i := 0; i < n; i++ { buffer[i] = 0 } } }
為了獲得更大的彈性,可以使用TCP 劫持者,它可以直接控制TCP 連線。然而,這種方法需要對網路程式設計有更深入的了解,並且不太推薦用於一般用例。
請注意,緩衝仍然可能發生在網路元件或客戶端應用程式中,因此它是對於評估您的特定用例以確定是否需要明確沖洗或替代解決方案至關重要。
以上是如何在 Golang 中傳輸 HTTP 回應並避免預設緩衝?的詳細內容。更多資訊請關注PHP中文網其他相關文章!