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

时间:2013-11-04 15:31:51

标签: http go http-post duplex

我听说here

  

一旦你在回复中写了任何内容,请求正文就会出现   关闭,阻止您阅读任何内容

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

2 个答案:

答案 0 :(得分:1)

我最终设法用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()

然后connnet.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()

答案 1 :(得分:0)

来自您所指的net/http docs

  

var ErrBodyReadAfterClose = errors.New(“http:无效读取已关闭   体“)

     

读取请求或响应时返回ErrBodyReadAfterClose   身体关闭后的身体。这通常发生在   在HTTP处理程序调用WriteHeader或Write之后读取body   ResponseWriter

然而,我尝试了你提到的博客文章中链接的代码,并且在go 1.1.2下工作正常,除非我首先编写超过大约4k的数据,r.ParseForm()返回ErrBodyReadAfterClose。< / p>

所以我认为答案是否定的,除非响应很短(低于4k),否则你不能进行全双工HTTP。

我会说完全双工HTTP请求不太可能是一个很大的好处,因为大多数客户端在完成发送请求之前不会尝试读取响应,所以你赢得的最多就是大小客户端中的TCP缓冲区&amp;服务器。如果超过这些缓冲区,则可能出现死锁,例如

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