HTTP/2 服务器推入 iOS 10
HTTP/2 Server Push in iOS 10
我正在尝试让服务器推送在 iOS 10 上运行。我正在使用 Akamai HTTP/2 演示。
以下是我测试服务器推送的尝试。
@interface ViewController () <NSURLSessionTaskDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: self delegateQueue: [NSOperationQueue mainQueue]];
NSString *displayArtUrl;
for(int i=0; i<378; i++) {
displayArtUrl = [NSString stringWithFormat:@"https://http2.akamai.com/demo/tile-%ld.png", (long)i];
NSURL *url = [NSURL URLWithString:displayArtUrl];
NSURLSessionDataTask *downloadTask = [defaultSession
dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
}];
[downloadTask resume];
}
}
- (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");
}
}
}
@end
不幸的是,日志显示获取类型始终是 NSURLSessionTaskMetricsResourceFetchTypeNetworkLoad,而我有时希望它是 NSURLSessionTaskMetricsResourceFetchTypeServerPush。服务器显然支持它,如网络演示所示。
...
2016-11-22 19:27:37.596205 HttpServerPush[2356:735927] protocol[h2] reuse[1] fetch:Network Load - https://http2.akamai.com/demo/tile-4.png
2016-11-22 19:27:37.596960 HttpServerPush[2356:735927] protocol[h2] reuse[1] fetch:Network Load - https://http2.akamai.com/demo/tile-5.png
2016-11-22 19:27:37.597877 HttpServerPush[2356:735927] protocol[h2] reuse[1] fetch:Network Load - https://http2.akamai.com/demo/tile-6.png
2016-11-22 19:27:37.603988 HttpServerPush[2356:735927] protocol[h2] reuse[1] fetch:Network Load - https://http2.akamai.com/demo/tile-1.png
2016-11-22 19:27:37.976911 HttpServerPush[2356:735927] protocol[h2] reuse[1] fetch:Network Load - https://http2.akamai.com/demo/tile-7.png
....
有人在 iOS 10 上 HTTP/2 服务器推送成功了吗?请求资产的方式是否遗漏了什么?
仅供参考,在这种情况下,Charles Proxy 似乎会妨碍您。启用它会导致 iOS 10 完全停止使用 HTTP/2。
...
2016-11-22 19:55:15.763 HttpServerPush[59822:1612935] protocol[http/1.1] reuse[1] fetch:Network Load - https://http2.akamai.com/demo/tile-8.png
2016-11-22 19:55:15.766 HttpServerPush[59822:1612935] protocol[http/1.1] reuse[1] fetch:Network Load - https://http2.akamai.com/demo/tile-11.png
2016-11-22 19:55:15.769 HttpServerPush[59822:1612935] protocol[http/1.1] reuse[1] fetch:Network Load - https://http2.akamai.com/demo/tile-9.png
2016-11-22 19:55:15.771 HttpServerPush[59822:1612935] protocol[http/1.1] reuse[1] fetch:Network Load - https://http2.akamai.com/demo/tile-12.png
...
据我所知,Akamai 演示页面目前没有推送任何资源。当服务器向客户端发送 PUSH_PROMISE
帧时发生推送。 nghttp
(可通过 brew 在 Mac OS X: brew install nghttp2
上安装)可用于显示服务器发送的帧:
$ nghttp -nv 'https://http2.akamai.com/demo' | grep 'PUSH_PROMISE'
$
另一方面,H2O HTTP服务器首页https://h2o.examp1e.net/确实推送资源:
$ nghttp -nv 'https://h2o.examp1e.net' | grep 'PUSH_PROMISE'
[ 0.587] recv PUSH_PROMISE frame <length=59, flags=0x04, stream_id=13>
[ 0.587] recv PUSH_PROMISE frame <length=33, flags=0x04, stream_id=13>
[ 0.588] recv PUSH_PROMISE frame <length=35, flags=0x04, stream_id=13>
[ 0.588] recv PUSH_PROMISE frame <length=24, flags=0x04, stream_id=13>
[ 0.588] recv PUSH_PROMISE frame <length=28, flags=0x04, stream_id=13>
$
HTTP/2 推送在 Safari 中被广泛认为是坏的。
不要认为这些信息是最新的,但上次我检查浏览器会接受并有时使用推送的资源,而其他时候则不会。
原始答案:
我正要回答你 HTTP/2 iOS 不支持推送,但后来我快速浏览了我们的页面:
并等待连接统计信息出现在右上角。 HTTP/2 iOS 10 支持推送!!
我正在尝试让服务器推送在 iOS 10 上运行。我正在使用 Akamai HTTP/2 演示。
以下是我测试服务器推送的尝试。
@interface ViewController () <NSURLSessionTaskDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: self delegateQueue: [NSOperationQueue mainQueue]];
NSString *displayArtUrl;
for(int i=0; i<378; i++) {
displayArtUrl = [NSString stringWithFormat:@"https://http2.akamai.com/demo/tile-%ld.png", (long)i];
NSURL *url = [NSURL URLWithString:displayArtUrl];
NSURLSessionDataTask *downloadTask = [defaultSession
dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
}];
[downloadTask resume];
}
}
- (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");
}
}
}
@end
不幸的是,日志显示获取类型始终是 NSURLSessionTaskMetricsResourceFetchTypeNetworkLoad,而我有时希望它是 NSURLSessionTaskMetricsResourceFetchTypeServerPush。服务器显然支持它,如网络演示所示。
...
2016-11-22 19:27:37.596205 HttpServerPush[2356:735927] protocol[h2] reuse[1] fetch:Network Load - https://http2.akamai.com/demo/tile-4.png
2016-11-22 19:27:37.596960 HttpServerPush[2356:735927] protocol[h2] reuse[1] fetch:Network Load - https://http2.akamai.com/demo/tile-5.png
2016-11-22 19:27:37.597877 HttpServerPush[2356:735927] protocol[h2] reuse[1] fetch:Network Load - https://http2.akamai.com/demo/tile-6.png
2016-11-22 19:27:37.603988 HttpServerPush[2356:735927] protocol[h2] reuse[1] fetch:Network Load - https://http2.akamai.com/demo/tile-1.png
2016-11-22 19:27:37.976911 HttpServerPush[2356:735927] protocol[h2] reuse[1] fetch:Network Load - https://http2.akamai.com/demo/tile-7.png
....
有人在 iOS 10 上 HTTP/2 服务器推送成功了吗?请求资产的方式是否遗漏了什么?
仅供参考,在这种情况下,Charles Proxy 似乎会妨碍您。启用它会导致 iOS 10 完全停止使用 HTTP/2。
...
2016-11-22 19:55:15.763 HttpServerPush[59822:1612935] protocol[http/1.1] reuse[1] fetch:Network Load - https://http2.akamai.com/demo/tile-8.png
2016-11-22 19:55:15.766 HttpServerPush[59822:1612935] protocol[http/1.1] reuse[1] fetch:Network Load - https://http2.akamai.com/demo/tile-11.png
2016-11-22 19:55:15.769 HttpServerPush[59822:1612935] protocol[http/1.1] reuse[1] fetch:Network Load - https://http2.akamai.com/demo/tile-9.png
2016-11-22 19:55:15.771 HttpServerPush[59822:1612935] protocol[http/1.1] reuse[1] fetch:Network Load - https://http2.akamai.com/demo/tile-12.png
...
据我所知,Akamai 演示页面目前没有推送任何资源。当服务器向客户端发送 PUSH_PROMISE
帧时发生推送。 nghttp
(可通过 brew 在 Mac OS X: brew install nghttp2
上安装)可用于显示服务器发送的帧:
$ nghttp -nv 'https://http2.akamai.com/demo' | grep 'PUSH_PROMISE'
$
另一方面,H2O HTTP服务器首页https://h2o.examp1e.net/确实推送资源:
$ nghttp -nv 'https://h2o.examp1e.net' | grep 'PUSH_PROMISE'
[ 0.587] recv PUSH_PROMISE frame <length=59, flags=0x04, stream_id=13>
[ 0.587] recv PUSH_PROMISE frame <length=33, flags=0x04, stream_id=13>
[ 0.588] recv PUSH_PROMISE frame <length=35, flags=0x04, stream_id=13>
[ 0.588] recv PUSH_PROMISE frame <length=24, flags=0x04, stream_id=13>
[ 0.588] recv PUSH_PROMISE frame <length=28, flags=0x04, stream_id=13>
$
HTTP/2 推送在 Safari 中被广泛认为是坏的。 不要认为这些信息是最新的,但上次我检查浏览器会接受并有时使用推送的资源,而其他时候则不会。
原始答案:
我正要回答你 HTTP/2 iOS 不支持推送,但后来我快速浏览了我们的页面:
并等待连接统计信息出现在右上角。 HTTP/2 iOS 10 支持推送!!