Go实战--golang中使用echo框架中的HTTP/2、Server Push(labstack
生命不止,继续 go go go !!! 继续echo web框架,今天搞一下http2。 HTTP2What is HTTP/2? The focus of the protocol is on performance; specifically,end-user perceived latency,network and server resource usage. One major goal is to allow the use of a single connection from browsers to a Web site. 新的二进制格式(Binary Format) 多路复用(MultiPlexing) header压缩 服务端推送(server push) 生成证书go run C:gosrccryptotlsgenerate_cert.go --host localhost 2017/11/22 10:06:58 written cert.pem 2017/11/22 10 :06:58 written key.pem
echo中的HTTP/2代码main.go: package main
import (
"fmt"
"net/http"
"github.com/labstack/echo"
)
func main() {
e := echo.New()
e.GET("/request",func(c echo.Context) error {
req := c.Request()
format := ` <code> Protocol: %s<br> Host: %s<br> Remote Address: %s<br> Method: %s<br> Path: %s<br> </code> `
return c.HTML(http.StatusOK,fmt.Sprintf(format,req.Proto,req.Host,req.RemoteAddr,req.Method,req.URL.Path))
})
e.Logger.Fatal(e.StartTLS(":1323","cert.pem","key.pem"))
}
浏览器输入: 结果: Protocol: HTTP/2.0
Host: localhost:1323
Remote Address: [::1]:1905
Method: GET
Path: /request
如果出现错误: 请检查是否输入的是https golang.org/x/net/http2文档地址: 获取: 代码main.go: package main
import (
"fmt"
"html"
"log"
"net/http"
"golang.org/x/net/http2"
)
func main() {
var srv http.Server
http2.VerboseLogs = true
srv.Addr = ":8080"
// This enables http2 support
http2.ConfigureServer(&srv,nil)
http.HandleFunc("/",func(w http.ResponseWriter,r *http.Request) {
fmt.Fprintf(w,"Hi tester %qn",html.EscapeString(r.URL.Path))
ShowRequestInfoHandler(w,r)
})
// Listen as https ssl server
// NOTE: WITHOUT SSL IT WONT WORK!!
log.Fatal(srv.ListenAndServeTLS("cert.pem","key.pem"))
}
func ShowRequestInfoHandler(w http.ResponseWriter,r *http.Request) {
w.Header().Set("Content-Type","text/plain")
fmt.Fprintf(w,"Method: %sn",r.Method)
fmt.Fprintf(w,"Protocol: %sn",r.Proto)
fmt.Fprintf(w,"Host: %sn",r.Host)
fmt.Fprintf(w,"RemoteAddr: %sn",r.RemoteAddr)
fmt.Fprintf(w,"RequestURI: %qn",r.RequestURI)
fmt.Fprintf(w,"URL: %#vn",r.URL)
fmt.Fprintf(w,"Body.ContentLength: %d (-1 means unknown)n",r.ContentLength)
fmt.Fprintf(w,"Close: %v (relevant for HTTP/1 only)n",r.Close)
fmt.Fprintf(w,"TLS: %#vn",r.TLS)
fmt.Fprintf(w,"nHeaders:n")
r.Header.Write(w)
}
浏览器输入: 结果: Hi tester "/"
Method: GET
Protocol: HTTP/2.0
Host: localhost:8080
RemoteAddr: [::1]:2750
RequestURI: "/"
URL: &url.URL{Scheme:"",Opaque:"",User:(*url.Userinfo)(nil),Host:"",Path:"/",RawPath:"",ForceQuery:false,RawQuery:"",Fragment:""}
Body.ContentLength: 0 (-1 means unknown)
Close: false (relevant for HTTP/1 only)
TLS: &tls.ConnectionState{Version:0x303,HandshakeComplete:true,DidResume:false,CipherSuite:0xc02f,NegotiatedProtocol:"h2",NegotiatedProtocolIsMutual:true,ServerName:"localhost",PeerCertificates:[]*x509.Certificate(nil),VerifiedChains:[][]*x509.Certificate(nil),SignedCertificateTimestamps:[][]uint8(nil),OCSPResponse:[]uint8(nil),TLSUnique:[]uint8{0xa6, 0x3c, 0xfe, 0x93, 0x15, 0x4f, 0x74, 0xfc, 0x97, 0xca, 0x73}}
Headers:
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 Accept-Encoding: gzip,deflate,br Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 Alexatoolbar-Alx_ns_ph: AlexaToolbar/alx-4.0 Cookie: _ga=GA1.1.981224509.1509938615 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/62.0.3202.94 Safari/537.36
Server PushServer Push是什么 简单来讲就是当用户的浏览器和服务器在建立链接后,服务器主动将一些资源推送给浏览器并缓存起来,这样当浏览器接下来请求这些资源时就直接从缓存中读取,不会在从服务器上拉了,提升了速率。举一个例子就是: Server Push原理是什么 要想了解server push原理,首先要理解一些概念。我们知道HTTP2传输的格式并不像HTTP1使用文本来传输,而是启用了二进制帧(Frames)格式来传输,和server push相关的帧主要分成这几种类型: HEADERS frame(请求返回头帧):这种帧主要携带的http请求头信息,和HTTP1的header类似。 DATA frames(数据帧) :这种帧存放真正的数据content,用来传输。 RST_STREAM(取消推送帧):这种帧表示请求关闭帧,简单讲就是当client不想接受某些资源或者接受timeout时会向发送方发送此帧,和PUSH_PROMISE frame一起使用时表示拒绝或者关闭server push。 了解了相关的帧类型,下面就是具体server push的实现过程了: Golang1.8中的Server Push代码main.go: package main
import (
"fmt"
"io/ioutil"
"net/http"
)
var image []byte
// preparing image
func init() {
var err error
image,err = ioutil.ReadFile("./image.png")
if err != nil {
panic(err)
}
}
// Send HTML and push image
func handlerHtml(w http.ResponseWriter,r *http.Request) {
pusher,ok := w.(http.Pusher)
if ok {
fmt.Println("Push /image")
pusher.Push("/image",nil)
}
w.Header().Add("Content-Type","text/html")
fmt.Fprintf(w,`<html><body><img src="/image"></body></html>`)
}
// Send image as usual HTTP request
func handlerImage(w http.ResponseWriter,"image/png")
w.Write(image)
}
func main() {
http.HandleFunc("/",handlerHtml)
http.HandleFunc("/image",handlerImage)
fmt.Println("start http listening :18443")
err := http.ListenAndServeTLS(":18443","server.crt","server.key",nil)
fmt.Println(err)
}
浏览器输入: 可以使用插件HTTP/2 and SPDY indicator echo框架中的Server Pushindex.html <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>HTTP/2 Server Push</title>
<link rel="stylesheet" href="/app.css">
<script src="/app.js"></script>
</head>
<body>
<img class="echo" src="/echo.png">
<h2>The following static files are served via HTTP/2 server push</h2>
<ul>
<li><code>/app.css</code></li>
<li><code>/app.js</code></li>
<li><code>/echo.png</code></li>
</ul>
</body>
</html>
main.go package main
import (
"net/http"
"github.com/labstack/echo"
)
func main() {
e := echo.New()
e.Static("/","static")
e.GET("/",func(c echo.Context) (err error) {
pusher,ok := c.Response().Writer.(http.Pusher)
if ok {
if err = pusher.Push("/app.css",nil); err != nil {
return
}
if err = pusher.Push("/app.js",nil); err != nil {
return
}
if err = pusher.Push("/echo.png",nil); err != nil {
return
}
}
return c.File("index.html")
})
e.Logger.Fatal(e.StartTLS(":1323","key.pem"))
}
浏览器输入: 参考: (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |