使用服务器推送
让我们重新运行服务器,并测试客户机。
对于HTTP / 1.1客户端:
$ go run ./h2-client.go -version 1
Got response 200: HTTP/1.1 Hello
服务器日志将显示:
Got connection: HTTP/1.1Handling 1st
Can't push to client
HTTP/1.1客户端传输连接产生一个 http.ResponseWriter 没有实现http.Pusher,这是有道理的。在我们的服务器代码中,我们可以选择在这种客户机的情况下该做什么。
对于HTTP/2客户:
go run ./h2-client.go -version 2
Got response 200: HTTP/2.0 Hello
服务器日志将显示:
Got connection: HTTP/2.0Handling 1st
Failed push: feature not supported
这很奇怪。我们的HTTP/2传输的客户端只得到了第一个“Hello”响应。日志表明连接实现了 http.Pusher 接口——但是一旦我们实际调用 Push() 函数——它就失败了。
排查发现,HTTP/2客户端传输设置了一个HTTP/2设置标志,表明推送是禁用的。
因此,目前没有选择使用Go客户机来使用服务器推送。
作为一个附带说明,google chrome作为一个客户端可以处理服务器推送。


服务器日志将显示我们所期望的,处理程序被调用两次,路径 / 和 /2nd,即使客户实际上只对路径 /:
Got connection: HTTP/2.0Handling 1st
Got connection: HTTP/2.0Handling 2nd
全双工通信
Go HTTP/2演示页面有一个echo示例,它演示了服务器和客户机之间的全双工通信。
让我们先用CURL来测试一下:
$ curl -i -XPUT --http2 https://http2.golang.org/ECHO -d hello
HTTP/2 200
content-type: text/plain; charset=utf-8
date: Tue, 24 Jul 2018 12:20:56 GMT
HELLO
我们把curl配置为使用HTTP/2,并将一个PUT/ECHO发送给“hello”作为主体。服务器以“HELLO”作为主体返回一个HTTP/2 200响应。但我们在这里没有做任何复杂的事情,它看起来像是一个老式的HTTP/1.1半双工通信,有不同的头部。让我们深入研究这个问题,并研究如何使用HTTP/2全双工功能。
服务器实现
下面是HTTP echo处理程序的简化版本(不使用响应)。它使用 http.Flusher 接口,HTTP/2添加到http.ResponseWriter。
type flushWriter struct {
w io.Writer
}
func (fw flushWriter) Write(p []byte) (n int, err error) {
n, err = fw.w.Write(p)
// Flush - send the buffered written data to the client
if f, ok := fw.w.(http.Flusher); ok {
f.Flush()
}
return
}
func echoCapitalHandler(w http.ResponseWriter, r *http.Request) {
// First flash response headers
if f, ok := w.(http.Flusher); ok {
f.Flush()
}
// Copy from the request body to the response writer and flush
// (send to client)
io.Copy(flushWriter{w: w}, r.Body)
}









