菜单

iOS HTTP/2 Server Push 探索

2019年3月1日 - 皇家前端

5,Server Push相关难题。

  1. 作者们知晓以后大家web的财富一般都以身处CDN上的,那么CDN的优势和server
    push的优势有什么分化呢,到底是哪些相比快呢?这些难题我也直接在切磋,本文的连带demo都只好算做1个演示,具体的线上进行还在拓展中。
  2. 鉴于HTTP2的有的新个性例如多路复用,server
    push等等都以依照同贰个域名的,所以那大概会对我们事先对于HTTP1的片段优化措施例如(能源拆分域名,合并等等)不必然适用。
  3. server
    push不仅能够当作拉取静态能源,我们的cgi请求即ajax请求同样能够选取server
    push来发送数据。
  4. 最健全的结果是CDN域名支持HTTP2,web server域名也还要扶助HTTP2。

 

参考资料:

  1. HTTP2官方正式:
  2. 维基百科:
  3. 皇家88娱乐网,1 赞 1 收藏
    评论

皇家88娱乐网 1

HTTP/2

后续echo web框架,明日搞一下http2。

澳门皇家赌场在线,HTTP2特性大概浏览

3,Server Push原理是什么样。

要想驾驭server
push原理,首先要明了一些定义。大家了解HTTP2传输的格式并不像HTTP1使用文本来传输,而是启用了二进制帧(Frames)格式来传输,和server
push相关的帧主要分为这几类别型:

  1. HEADE凯雷德S
    frame(请求重临头帧):那种帧首要指点的http请求头新闻,和HTTP1的header类似。
  2. DATA frames(数据帧) :那种帧存放真正的数量content,用来传输。
  3. PUSH_PROMISE
    frame(推送帧):那种帧是由server端发送给client的帧,用来代表server
    push的帧,那种帧是达成server push的第壹帧类型。
  4. RST_STREAM(撤废推送帧):那种帧表示请求关闭帧,简单讲就是当client不想接受有个别财富照旧收受timeout时会向发送方发送此帧,和PUSH_PROMISE
    frame一起使用时表示拒绝或然关闭server push。

Note:HTTP2.0相关的帧其实包蕴10种帧,便是因为底部数据格式的变更,才为HTTP2.0推动众多的特点,帧的引入不仅有益减弱数量,也方便数据的安全性和保障传输性。

驾驭了连带的帧类型,上边正是具体server push的完成进程了:

  1. 由多路复用我们得以清楚HTTP第22中学对于同二个域名的伸手会选拔一条tcp链接而用不相同的stream
    ID来分别各自的乞请。
  2. 当client使用stream
    1请求index.html时,server平常处理index.html的请求,并得以查出index.html页面还将要会呈请index.css和index.js。
  3. server使用stream 1发送PUSH_PROMISE
    frame给client告诉client小编那边能够使用stream 2来推送index.js和stream
    3来推送index.css财富。
  4. server使用stream 1不奇怪的出殡和埋葬HEADEEnclaveS frame和DATA
    frames将index.html的始末重返给client。
  5. client接收到PUSH_PROMISE frame得知stream 2和stream
    3来接收推送财富。
  6. server获得index.css和index.js便会发送HEADE哈弗S frame和DATA
    frames将能源发送给client。
  7. client得到push的财富后会缓存起来当呼吁这些能源时会从平素从从缓存中读取。

下图表示了整整工艺流程:

皇家88娱乐网 2

Server Push 怎么用

生命不息,继续 go go go !!!

浏览器支持

主流浏览器都只扶助 HTTP/2 Over TLS

1,HTTP2的新特色。

关于HTTP2的新天性,读着能够参考小编前边的稿子,那里就不在多说了,本篇文章重要讲一下server
push这些天性。

HTTP,HTTP2.0,SPDY,HTTPS你应有清楚的一部分事

 

iOS 使用 HTTP/2 Server Push

Apple 在那方面做的很好,基本落到实处了客户端无感调用http/2 server
push。不过小编查阅了多少材料,今后唯有iOS 10 支持 http/2。

直白上代码吧:

#import "ViewController.h"

@interface ViewController ()<NSURLSessionDelegate>

@property(nonatomic,strong)NSURLSession *session;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

}
#pragma mark - Touch
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [self urlSession];
}
#pragma mark - 发送请求
- (void)urlSession
{
    NSURL *url = [NSURL URLWithString:@"https://localhost:3000"];

    //发送HTTPS请求是需要对网络会话设置代理的
    _session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];

    NSURLSessionDataTask *dataTask = [_session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
        // 收到该次请求后,立即请求下次的内容
        [self urlSessionPush];

    }];

    [dataTask resume];
}

- (void)urlSessionPush
{
    NSURL *url = [NSURL URLWithString:@"https://localhost:3000/Users/f.li/Desktop/http2-nodeServer/newpush.json"];
    NSURLSessionDataTask *dataTask = [_session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
    }];
    [dataTask resume];
}

#pragma mark - URLSession Delegate
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler
{
    // 这里还要设置下 plist 中设置 ATS
    if (![challenge.protectionSpace.authenticationMethod isEqualToString:@"NSURLAuthenticationMethodServerTrust"])
    {
        return;
    }
    NSURLCredential *credential = [[NSURLCredential alloc] initWithTrust:challenge.protectionSpace.serverTrust];
    completionHandler(NSURLSessionAuthChallengeUseCredential,credential);
}


- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didFinishCollectingMetrics:(NSURLSessionTaskMetrics *)metrics
{
    NSArray *fetchTypes = @[ @"Unknown", @"Network Load", @"Server Push", @"Local Cache"];

    for(NSURLSessionTaskTransactionMetrics *transactionMetrics in [metrics transactionMetrics])
    {

        NSLog(@"protocol[%@] reuse[%d] fetch:%@ - %@", [transactionMetrics networkProtocolName], [transactionMetrics isReusedConnection], fetchTypes[[transactionMetrics resourceFetchType]], [[transactionMetrics request] URL]);

        if([transactionMetrics resourceFetchType] == NSURLSessionTaskMetricsResourceFetchTypeServerPush)
        {
            NSLog(@"Asset was server pushed");
        }
    }
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

分级看下服务端和客户端的Log:
客户端:

Http2ServerPush[2525:274943] protocol[h2] reuse[0] fetch:Network Load - https://localhost:3000/
Http2ServerPush[2525:274943] {"message":" http2.0 server is ok"}
Http2ServerPush[2525:274943] protocol[h2] reuse[1] fetch:Server Push - https://localhost:3000/Users/f.li/Desktop/http2-nodeServer/newpush.json
Http2ServerPush[2525:274943] Asset was server pushed
Http2ServerPush[2525:274943] {"message":"newPush"}

服务端:

http2-nodeServer npm start

> http2-nodeServer@1.0.0 start /Users/f.li/Desktop/http2-nodeServer
> node index.js

listen on 3000
success
newpush end

总的来说确实是客户端发出了一回呼吁,不过服务端只响应了三回(该次响应+ server
push)

Server Push

Server Push是什么

简易来讲正是当用户的浏览器和服务器在成立链接后,服务器主动将一部分能源推送给浏览器并缓存起来,那样当浏览器接下去请求那几个财富时就径直从缓存中读取,不会在从服务器上拉了,进步了速率。举一个事例正是:
假若二个页面有三个财富文件index.html,index.css,index.js,当浏览器请求index.html的时候,服务器不仅重返index.html的剧情,同时将index.css和index.js的始末push给浏览器,当浏览器下次呼吁那2三个文件时就足以平素从缓存中读取了。

Server Push原理是怎么

要想精晓server
push原理,首先要明白一些概念。大家清楚HTTP2传输的格式并不像HTTP1使用文本来传输,而是启用了二进制帧(Frames)格式来传输,和server
push相关的帧首要分为那三种档次:

HEADE奥德赛S
frame(请求重临头帧):这种帧重要指引的http请求头信息,和HTTP1的header类似。

DATA frames(数据帧) :那种帧存放真正的多少content,用来传输。
PUSH_PROMISE
frame(推送帧):这种帧是由server端发送给client的帧,用来代表server
push的帧,那种帧是落实server push的要害帧类型。

RST_STREAM(撤消推送帧):那种帧表示请求关闭帧,简单讲正是当client不想接受一些财富依然收受timeout时会向发送方发送此帧,和PUSH_PROMISE
frame一起行使时表示拒绝或许关闭server push。

摸底了连带的帧类型,上面正是现实server push的贯彻过程了:
由多路复用大家能够精通HTTP第22中学对此同1个域名的乞求会利用一条tcp链接而用不一致的stream
ID来差异各自的呼吁。
当client使用stream
1请求index.html时,server寻常处理index.html的乞求,并能够识破index.html页面还就要会呈请index.css和index.js。
server使用stream 1发送PUSH_PROMISE
frame给client告诉client作者这边能够采用stream 2来推送index.js和stream
3来推送index.css财富。
server使用stream 1通常的发送HEADEEnclaveS frame和DATA
frames将index.html的内容再次来到给client。
client接收到PUSH_PROMISE frame得知stream 2和stream 3来接收推送能源。
server获得index.css和index.js便会发送HEADE福特ExplorerS frame和DATA
frames将能源发送给client。
client得到push的能源后会缓存起来当呼吁那个财富时会从第三手从从缓存中读取。

一分钟预览 HTTP2 表征和抓包分析

2016/09/26 · JavaScript
· HTTP/2

原稿出处: 段隆贤   

4,Server Push怎么用。

既然server
push这么神奇,那么大家怎么着利用呢?怎么设置服务器push哪些文件呢?

第壹并不是享有的服务器都帮衬server
push,nginx近来还不援救这么些特点,能够在nginx的官方博客上收获印证,不过Apache和nodejs都早就支撑了server
push这三个特征,需要证可瑞康些的是server
push那本性子是依据浏览器和服务器的,所以浏览器并从未提供相应的js
api来让用户平素操作和决定push的内容,所以只好是通过header音讯和server的安顿来达成具体的push内容,本文主要以nodejs来验证实际什么运用server
push这一特点。

有备无患干活:下载nodejs
http2支持,本地运营nodejs服务。

1. 先是我们选取nodejs搭建基本的server:

JavaScript

var http2 = require(‘http2’);   var url=require(‘url’); var
fs=require(‘fs’); var mine=require(‘./mine’).types; var
path=require(‘path’);   var server = http2.createServer({   key:
fs.readFileSync(‘./zs/localhost.key’),   cert:
fs.readFileSync(‘./zs/localhost.crt’) }, function(request, response) {
    var pathname = url.parse(request.url).pathname;     var realPath =
path.join(“my”, pathname);    //那里设置自个儿的文件名称;       var
pushArray = [];     var ext = path.extname(realPath);     ext = ext ?
ext.slice(1) : ‘unknown’;     var contentType = mine[ext] ||
“text/plain”;       if (fs.existsSync(realPath)) {  
        response.writeHead(200, {             ‘Content-Type’:
contentType         });  
        response.write(fs.readFileSync(realPath,’binary’));       } else
{       response.writeHead(404, {           ‘Content-Type’: ‘text/plain’
      });         response.write(“This request URL ” + pathname + ” was
not found on this server.”);       response.end();     }   });  
server.listen(443, function() {   console.log(‘listen on 443’); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
var http2 = require(‘http2’);
 
var url=require(‘url’);
var fs=require(‘fs’);
var mine=require(‘./mine’).types;
var path=require(‘path’);
 
var server = http2.createServer({
  key: fs.readFileSync(‘./zs/localhost.key’),
  cert: fs.readFileSync(‘./zs/localhost.crt’)
}, function(request, response) {
    var pathname = url.parse(request.url).pathname;
    var realPath = path.join("my", pathname);    //这里设置自己的文件名称;
 
    var pushArray = [];
    var ext = path.extname(realPath);
    ext = ext ? ext.slice(1) : ‘unknown’;
    var contentType = mine[ext] || "text/plain";
 
    if (fs.existsSync(realPath)) {
 
        response.writeHead(200, {
            ‘Content-Type’: contentType
        });
 
        response.write(fs.readFileSync(realPath,’binary’));
 
    } else {
      response.writeHead(404, {
          ‘Content-Type’: ‘text/plain’
      });
 
      response.write("This request URL " + pathname + " was not found on this server.");
      response.end();
    }
 
});
 
server.listen(443, function() {
  console.log(‘listen on 443’);
});

这几行代码就是简单搭建三个nodejs
http2服务,打开chrome,大家能够见见有着请求都走了http2,同时也能够证实多路复用的特征。

皇家88娱乐网 3

此处须求专注几点:

  1. 始建http2的nodejs服务必须时依据https的,因为以往主流的浏览器都要援救SSL/TLS的http2,证书和私钥能够友善通过OPENSSL生成。
  2. node http2的连带api和例行的node httpserver相同,能够一直利用。

  3. 安装大家的server push:

JavaScript

var pushItem = response.push(‘/css/bootstrap.min.css’, {        request:
{             accept: ‘*/\*’        },       response: {
            ‘content-type’: ‘text/css’      } });
pushItem.end(fs.readFileSync(‘/css/bootstrap.min.css’,’binary’));

1
2
3
4
5
6
7
8
9
var pushItem = response.push(‘/css/bootstrap.min.css’, {
       request: {
            accept: ‘*/\*’
       },
      response: {
            ‘content-type’: ‘text/css’
     }
});
pushItem.end(fs.readFileSync(‘/css/bootstrap.min.css’,’binary’));

作者们设置了bootstrap.min.css来经过server
push到大家的浏览器,大家能够在浏览器中查阅:

皇家88娱乐网 4

能够看出,运转server push的财富timelime十分的快,大大加速了css的取得时间。

此地须要专注上面几点:

  1. 大家调用response.push(),便是一对一于server发起了PUSH_PROMISE
    frame来告诉浏览器bootstrap.min.css将会由server push来博取。
  2. response.push()重临的对象时八个健康的ServerResponse,end(),writeHeader()等艺术都得以健康调用。
  3. 那边一旦针对某些能源调用response.push()即发起PUSH_PROMISE
    frame后,要办好容错机制,因为浏览器在下次央求那一个能源时会且只会等待这些server
    push回来的资源,那里要盘活超时和容错即上边包车型地铁代码:
  4. JavaScript

    try {
        pushItem.end(fs.readFileSync(‘my/css/bootstrap.min.css’,’binary’));
        } catch(e) {        response.writeHead(404, {           
    ‘Content-Type’: ‘text/plain’        });        response.end(‘request
    error’); }   pushItem.stream.on(‘error’, function(err){
        response.end(err.message); });   pushItem.stream.on(‘finish’,
    function(err){    console.log(‘finish’); });

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    try {
        pushItem.end(fs.readFileSync(‘my/css/bootstrap.min.css’,’binary’));
        } catch(e) {
           response.writeHead(404, {
               ‘Content-Type’: ‘text/plain’
           });
           response.end(‘request error’);
    }
     
    pushItem.stream.on(‘error’, function(err){
        response.end(err.message);
    });
     
    pushItem.stream.on(‘finish’, function(err){
       console.log(‘finish’);
    });

    地点的代码你或然会发现许多和例行nodejs的httpserver分化等的东西,那正是stream,其实全部http2都以以stream为单位,那里的stream其实能够知晓成三个呼吁,更加多的api能够参考:node-http2。

  5. 最终给大家推荐1个鬼子写的专门服务http2的node
    server有兴趣的能够尝试一下。

参考文献

HTTP2

What is HTTP/2?
HTTP/2 is a replacement for how HTTP is expressed “on the wire.” It is
not a ground-up rewrite of the protocol; HTTP methods, status codes and
semantics are the same, and it should be possible to use the same APIs
as HTTP/1.x (possibly with some small additions) to represent the
protocol.

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)
HTTP1.x的剖析是依照文本。基于文本协议的格式解析存在先性子缺陷,文本的表现情势有三种性,要达成健壮性考虑的现象必然很多,二进制则差别,只认0和1的构成。基于那种设想HTTP2.0的商谈分析决定运用二进制格式,落成方便且健壮。

多路复用(MultiPlexing)
即一连共享,即每三个request都以是作为连接共享机制的。1个request对应三个id,那样3个连接上可以有几个request,每一种连接的request能够私行的插花在一齐,接收方能够依照request的
id将request再归属到各自区别的服务端请求里面。多路复用原理图:

header压缩
HTTP2.0施用encoder来压缩须要传输的header大小,通信双方分别cache一份header
田野(field)s表,既制止了再次header的传导,又减小了索要传输的尺寸。

服务端推送(server push)
同SPDY一样,HTTP2.0也具有server push功能。

最后

说到底,HTTP2有更高的传输速度,更少的财富占用,能够去除种种品质优化tricks(如css
sprite,inline-image.)
转载WEB开发的美好今后T.T

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图