来自 Go 服务器的连续分块 HTTP 响应
为了创建一个连续传输数据块的 Go HTTP 服务器,您已经遇到了挑战。您的客户端不会按预期每秒接收数据块,而是仅在 5 秒的持续时间后收到完整的响应。此外,您希望在传输结束时将 Content-Length 标头发送为 0。
要解决此问题,必须将 Flusher 接口集成到服务器实现中。这是代码的修改版本:
package main import ( "fmt" "io" "log" "net/http" "time" ) func main() { http.HandleFunc("/test", HandlePost) log.Fatal(http.ListenAndServe(":8080", nil)) } func HandlePost(w http.ResponseWriter, r *http.Request) { flusher, ok := w.(http.Flusher) if !ok { panic("expected http.ResponseWriter to be an http.Flusher") } w.Header().Set("X-Content-Type-Options", "nosniff") ticker := time.NewTicker(time.Second) go func() { for t := range ticker.C { io.WriteString(w, "Chunk") fmt.Println("Tick at", t) flusher.Flush() } }() time.Sleep(time.Second * 5) ticker.Stop() fmt.Println("Finished: should return Content-Length: 0 here") w.Header().Set("Content-Length", "0") }
通过在写入每个块后调用 Flusher.Flush(),您可以触发“分块”编码并发送单独的块。这确保客户端在数据可用时接收数据。
验证此行为可以通过 telnet 实现,如下所示:
$ telnet localhost 8080 Trying ::1... Connected to localhost. Escape character is '^]'. GET / HTTP/1.1 HTTP/1.1 200 OK Date: Tue, 02 Jun 2015 18:16:38 GMT Content-Type: text/plain; charset=utf-8 Transfer-Encoding: chunked 9 Chunk #1 9 Chunk #2 ...
此修改后的代码可以发送连续分块 HTTP 响应来自你的 Go 服务器。请记住验证您的 ResponseWriters 是否支持跨多个 goroutine 的并发访问,以获得最佳性能。
以上是为什么我的 Go HTTP Server 在延迟后才发送分块数据,如何将 Content-Length 设置为 0?的详细内容。更多信息请关注PHP中文网其他相关文章!