gpt4 book ai didi

http - 在 Golang 中没有缓冲 http.ResponseWritter

转载 作者:IT老高 更新时间:2023-10-28 13:00:04 26 4
gpt4 key购买 nike

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

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 的邮件列表中找到了帮助。有两种方法可以实现:使用 hijacker允许接管 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 < n; i++ {
buffer[i] = 0
}
}
}

上次更新

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

最佳答案

正如 the documentation 中所暗示的那样,部分ResponseWriter可能实现Flusher接口(interface)。

这意味着你可以这样做:

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")
}

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

关于http - 在 Golang 中没有缓冲 http.ResponseWritter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19292113/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com