当前位置: 首页 > 面试题库 >

未在Golang中缓冲http.ResponseWritter

齐昊焱
2023-03-14
问题内容

我正在用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 < n; i++ {
      buffer[i] = 0
    }
  } 
}

最后更新

更好: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")
}

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



 类似资料:
  • 问题内容: 是缓冲还是无缓冲? 我读到这是的对象,并且是所引用的对象的类型。 而且它们都是Unbuffered的,所以为什么要刷新unbuffered …是否可以刷新unbuffered,我已经读过它们被立即写入。 问题答案: 是“标准”输出。在大多数操作系统上,终端io被缓冲,并且支持分页。 在Javadoc中, “标准”输出流。该流已经打开并且准备接受输出数据。通常,此流对应于主机环境或用户指

  • 问题内容: 我有: 哪个追加到缓冲区,是否可以写入缓冲区的开头? 问题答案: 由于基础不是从导出的,因此您可以使用: 试试这个The Go Playground: 输出:

  • 我正在阅读有关流的信息,发现我们可以使用setvbuf()函数来控制流......它写的是在行缓冲模式中,当遇到换行符时流将数据发送到文件中,在无缓冲状态下没有缓冲......所以我写了以下代码...... 所以我认为,因为这些是无缓冲流,所以输入应该在我写入屏幕后立即发送到标准输出。。。但程序在写入每一行后等待我按enter键,然后屏幕上只显示输出(由于fwrite)。。。我的问题是,当这些是无

  • 问题内容: 我有一个简单的从Erlang到Golang的端口示例,将数据从Erlang传递到Golang并回显响应。 问题是我可以传输的数据量似乎限制为2 ^ 8字节(请参见下文)。我认为问题可能出在Golang端(没有创建足够大的缓冲区),但是用bufio.NewReaderSize替换bufio.NewReader无效。因此,我现在认为问题可能出在Erlang一方。 我该怎么做才能增加缓冲区大

  • 正在为以下内容编写javadoc: 但是,将缓冲的输入流传入真的是一个问题吗?因此: 是否将is缓冲到bis中,或者java是否检测到is已缓冲并设置bis=is?如果是,不同的缓冲区大小是否会有所不同?如果没有,为什么不呢<注意:我说的是输入流,但实际上这个问题也适用于输出流

  • 问题内容: 我碰到一行,命令的输出已完全缓冲。这是什么意思? 问题答案: 在线C11标准 7.21.3 / 3: 当流没有 缓冲时 ,字符应尽快从源或目标出现。否则,字符可能会作为块被累积并传输到主机环境或从主机环境传输。当流被 完全缓冲时 ,打算在填充缓冲区时将字符作为块与主机环境进行传输。当流被 行缓冲时 ,当遇到换行符时,字符打算作为块与主机环境进行传输。此外,当填充缓冲区,在无缓冲流上请求