我听说here
一旦你在回复中写了任何内容,请求正文就会出现 关闭,阻止您阅读任何内容
如果这是真的,我怎样才能编写一个正确的双工处理程序,它能够从请求体读取,进行某种转换,然后以流式方式写入响应体,就像人们在节点中那样.js?
答案 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()
然后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()
答案 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;服务器。如果超过这些缓冲区,则可能出现死锁,例如