首页 > 后端开发 > Golang > 如何在 Golang 中传输 HTTP 响应并避免默认缓冲?

如何在 Golang 中传输 HTTP 响应并避免默认缓冲?

Susan Sarandon
发布: 2024-12-30 05:07:13
原创
608 人浏览过

How Can I Stream HTTP Responses in Golang and Avoid Default Buffering?

Golang 中的流式 HTTP 响应:绕过默认缓冲

本指南解决了 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 劫持者,它可以直接控制 TCP 连接。然而,这种方法需要对网络编程有更深入的了解,并且不太推荐用于一般用例。

注意事项

请注意,缓冲仍然可能发生在网络组件或客户端应用程序中,因此它是对于评估您的具体用例以确定是否需要显式冲洗或替代解决方案至关重要。

以上是如何在 Golang 中传输 HTTP 响应并避免默认缓冲?的详细内容。更多信息请关注PHP中文网其他相关文章!

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