我正在用 Go 编写一个简单的网络应用程序,我希望我的响应被流式传输到客户端(即,一旦请求被完全处理,就不会缓冲并以块的形式发送):
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 < n; i++ {
buffer[i] = 0
}
}
}
最后更新
更好:http : //play.golang.org/p/PpbPyXbtEs
catspeake
梵蒂冈之花
相关分类