验证HTTP/2的Server Push功能

Server Push是HTTP/2的一项重要功能,主流浏览器均早已支持。 去年推出的iOS 9时,NSURLSession已支持HTTP/2,但经验证发现其并不支持Server Push。今年WWDC上宣称iOS 10中NSURLSession支持该功能,咱们来验证一下。

1. 配置TLS

虽然HTTP/2并不强制要求TLS,但是目前主流浏览器为了推动数据的安全性,都只支持带TLS的HTTP/2,即我们必须得通过https形式访问。

如果没有证书,可以通过https://certbot.eff.org/ 申请免费证书,拿到cert.pem, privkey.pem

2. 服务端

服务端的示例程序我们采用Golang编写,其1.6版本的net/http包就已经支持HTTP/2了,具体可参考https://http2.golang.org/

我们参考其clockstream例子,让服务端每隔1秒往客户端推送时间戳(示例代码),主要代码片段如下:
ServeHTTP(w http.ResponseWriter, r *http.Request) { clientGone := w.(http.CloseNotifier).CloseNotify() w.Header().Set("Content-Type", "text/plain") ticker := time.NewTicker(1 * time.Second) defer ticker.Stop() for { fmt.Fprintf(w, "%v\n", time.Now()) w.(http.Flusher).Flush() select { case <-ticker.C: //监听定时器 case <-clientGone: log.Printf("Client %v disconnected from the clock", r.RemoteAddr) return //返回即关闭连接 } } }

3. 客户端

基于NSURLSessionDataTask,注意要使用delegate回调获取持续的推送数据,使用completionHandler拿不到数据。客户端主要代码片段如下:
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data { // 如果服务端每次推送的数据包过大,会出现分片,要进行包的拼接 NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); }

4. 应用场景

a业务的推送接口 https://.../push-a 
b业务的推送接口 https://.../push-b 
普通接口 https://.../get-info  

由于HTTP/2是在TCP连接上虚拟多个Stream,因此上述各接口都在同一个TCP连接上传输数据。这样可以做到:接口设计优雅、隔离性较好、性能亦优

对直接基于TCP或WebSocket的编程需求会不会慢慢变少?

你可能感兴趣的:(验证HTTP/2的Server Push功能)