如何在Go中执行HTTP双工处理程序?

如何在Go中执行HTTP双工处理程序?,http,go,http-post,duplex,Http,Go,Http Post,Duplex,我听说了 在响应中写入任何内容后,请求主体将 关闭,防止您从中读取任何内容 如果这是真的,我如何编写一个合适的双工处理程序,它能够读取请求体,进行某种转换,然后以流式方式写入响应体,就像人们在node.js中所做的那样?来自您所指的 var ErrBodyReadAfterClose=errors.New(“http:invalid Read on closed 正文) 读取请求或响应时返回ErrBodyReadAfterClose 车身关闭后的车身。这通常发生在 在HTTP处理程序调用Writ

我听说了

在响应中写入任何内容后,请求主体将 关闭,防止您从中读取任何内容

如果这是真的,我如何编写一个合适的双工处理程序,它能够读取请求体,进行某种转换,然后以流式方式写入响应体,就像人们在node.js中所做的那样?

来自您所指的

var ErrBodyReadAfterClose=errors.New(“http:invalid Read on closed 正文)

读取请求或响应时返回ErrBodyReadAfterClose 车身关闭后的车身。这通常发生在 在HTTP处理程序调用WriteHeader或对其 应答器

但是,我尝试了您提到的博客文章中链接的代码,它在go 1.1.2下运行良好,除非我首先写入超过4k的数据,在这种情况下,
r.ParseForm()
返回
ErrBodyReadAfterClose

所以我认为答案是否定的,除非响应很短(低于4k),否则一般情况下不能在go中使用全双工HTTP

我想说的是,执行全双工HTTP请求不太可能是一个很大的好处,尽管大多数客户端在完成发送请求之前不会尝试读取响应,因此您将赢得的最大好处是客户端和服务器中TCP缓冲区的大小。如果超过这些缓冲区,则可能出现死锁,例如

  • 客户端正在发送请求
  • 服务器正在发送响应
  • 服务器缓冲区获得完整的发送响应
  • 服务器块
  • 服务器不再读取客户端请求
  • 客户端缓冲区已满
  • 客户端块
  • 死锁

我最终通过http.Hijacker
成功地做到了这一点

在发出请求并解析请求头之后,我可以读取
*http.request.Body
,然后劫持连接并写入,同时如下所示:

hj, ok := w.(http.Hijacker)
if !ok {
    http.Error(w, "hijacking not supported", 500)
    return
}

conn, bufrw, err := hj.Hijack()
if err != nil {
    http.Error(w, err.Error(), 500)
    return
}
defer conn.Close()
然后,
conn
是一个
net.conn
,它是到客户端的底层TCP连接,
bufrw
是一个
*bufio.ReadWriter
,要在不关闭主体的情况下编写响应,我所要做的就是

_, err = bufrw.WriteString("HTTP/1.1 200 OK\n\n")
_, err = bufrw.WriteString("this")
_, err = bufrw.WriteString("is")
_, err = bufrw.WriteString("the")
_, err = bufrw.WriteString("response")
_, err = bufrw.WriteString("body")
然后我不确定这一点,但也许有人可以完成答案,偶尔用

err := bufrw.Flush()

我不知道大多数客户机的情况,但是node.js客户机都可以做到,这就是我的来源。如果这将成为一个问题,我将不得不更好地处理缓冲区