首页 > 后端开发 > Golang > 为什么我的 Go HTTP Server 在延迟后才发送分块数据,如何将 Content-Length 设置为 0?

为什么我的 Go HTTP Server 在延迟后才发送分块数据,如何将 Content-Length 设置为 0?

Barbara Streisand
发布: 2024-12-04 08:12:13
原创
406 人浏览过

Why Does My Go HTTP Server Only Send Chunked Data After a Delay, and How Can I Set Content-Length to 0?

来自 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中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板