登录
首页 >  Golang >  Go问答

在 Golang 中没有缓冲 http.ResponseWritter

来源:Golang技术栈

时间:2023-04-15 12:36:16 236浏览 收藏

珍惜时间,勤奋学习!今天给大家带来《在 Golang 中没有缓冲 http.ResponseWritter》,正文内容主要涉及到golang等等,如果你正在学习Golang,或者是对Golang有疑问,欢迎大家关注我!后面我会持续更新相关内容的,希望都能帮到正在学习的大家!

问题内容

我正在用 Go 编写一个简单的 Web 应用程序,我希望将我的响应流式传输到客户端(即,一旦请求完全处理,就不会缓冲并以块的形式发送):

func handle(res http.ResponseWriter, req *http.Request) {
  fmt.Fprintf(res, "sending first line of data")
  sleep(10) //not real code
  fmt.Fprintf(res, "sending second line of data")
}

从客户端的角度来看,两条线会同时发送。任何建议表示赞赏:)

在@dystroy 回答后编辑

在我个人进行的每次写入后都可以刷新,但在我的用例中这还不够:

cmd := exec.Command("a long command that outputs lots of lines")
cmd.Stdout = res //where res is a http.ResponseWritter
cmd.Stderr = res
err := cmd.Run()

我希望我的输出cmd也被刷新。无论如何要“自动刷新” ResponseWritter ?

解决方案

我在 golang 的邮件列表上找到了帮助。有两种方法可以实现这一点:使用允许接管 HTTP 的底层 TCP 连接的劫持者,或者在将写入和刷新的 go 例程中通过管道传输命令的 stdout 和 stderr:

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 

最后更新

更好:http ://play.golang.org/p/PpbPyXbtEs

正确答案

正如文档中所暗示的那样,有些人ResponseWriter可能会实现该Flusher接口。

这意味着您可以执行以下操作:

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()
  } else {
     log.Println("Damn, no flush");
  }
  sleep(10) //not real code
  fmt.Fprintf(res, "sending second line of data")
}

请注意,缓冲可能发生在网络或客户端的许多其他地方。

以上就是《在 Golang 中没有缓冲 http.ResponseWritter》的详细内容,更多关于golang的资料请关注golang学习网公众号!

声明:本文转载于:Golang技术栈 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>