HTTP
- 超文本傳輸協(xié)議(HyperText Transfer Protocol)
- 客戶端與服務(wù)器應(yīng)答標(biāo)準(zhǔn)
- 基于TCP/IP協(xié)議的應(yīng)用層協(xié)議
- 91年發(fā)布HTTP/0.9,96年HTTP/1.0, 99年HTTP/1.1
- 2015年HTTP/2 Spec 發(fā)布 RFC 7540
HTTP/0.9 - HTTP/1.1
- 0.9僅有一個(gè)Get方法
- 1.0增加若干內(nèi)容如Post Head,不支持永久TCP連接...
- 1.1版本增加更多內(nèi)容,支持持久連接,管道機(jī)制,緩存...
HTTP面臨的問(wèn)題
- TCP不能夠充分被利用
- 網(wǎng)絡(luò)差就會(huì)延遲
- 目前優(yōu)化HTTP的方案都比較繁瑣
- HTTP包含太多的細(xì)節(jié)和可選部分,過(guò)于龐大
- HTTP Pipelinging(通過(guò)管線提高TCP利用率),會(huì)隊(duì)頭阻塞(Head-of-line blocking)
- 延遲,HTTP Streaming延遲
- 請(qǐng)求的內(nèi)容越來(lái)越大

目前的解決方法
- 合并腳本
- 樣式表
- 圖片嵌入CSS
- 域名分片
SPDY(Speed)
- 由Google開(kāi)發(fā),設(shè)計(jì)目的在于降低網(wǎng)頁(yè)的加載時(shí)間
- SPDY不用于替換HTTP,只是修改了HTTP的傳輸方式
- 有多路復(fù)用,優(yōu)先級(jí),和壓縮的特性
- 僅支持在TLS(安全傳輸層協(xié)議)層
- SPDY是Google的注冊(cè)商標(biāo)
HTTP/2
- 基于SPDY草案修改
- 在現(xiàn)有協(xié)議上之上構(gòu)建的新協(xié)議,保留現(xiàn)有
- 更好的利用TCP特性來(lái)減少傳輸過(guò)程中的等待和暫停
- 更好的Web體驗(yàn)
- HTTP/2 是google開(kāi)發(fā)的 SPDY協(xié)議的一個(gè)子集
- 解決隊(duì)頭阻塞(Head-of-line blocking)問(wèn)題
- 下一個(gè)協(xié)議是HTTP/3
- RFC 7540
HTTP/2特性
與HTTP1.x兼容
使用NPN或者ALPN在請(qǐng)求之前確定應(yīng)該如何使用哪種協(xié)議來(lái)通訊.
- ALPN(Application Layer Protocol Negotiation)(HTTP2)
- NPN(Next Protocol Negotiation)(SYPD)
NPN與ALPN的區(qū)別在于: 誰(shuí)來(lái)決定會(huì)話所使用的協(xié)議
ALPN:客戶端先發(fā)送一個(gè)協(xié)議優(yōu)先級(jí)列表給服務(wù)器,有服務(wù)器選擇合適的
NPN:服務(wù)通知客戶端所有它支持的格式,客戶端來(lái)選合適的進(jìn)行通信
NPN已經(jīng)被ALPN取代
二進(jìn)制協(xié)議
- HTTP由文本協(xié)議變成二進(jìn)制協(xié)議
- 為了更好的實(shí)現(xiàn)成幀,使用文本再數(shù)據(jù)處理會(huì)很繁瑣
- 一個(gè)幀包含數(shù)據(jù)幀和頭幀
-
使用curl或者Wireshark來(lái)解析
幀
- 連接建立之后之后用幀來(lái)傳輸數(shù)據(jù)
- Length表示幀的大小
- Type類型定義了剩余的幀報(bào)頭和幀主體將如何被解釋
- Flags在不同幀類型賦予不同的語(yǔ)義
- StreamIdentifier流的標(biāo)識(shí)符號(hào),用于確定是那個(gè)流的幀
- FramePayload 數(shù)據(jù)
- 目前已定義的幀有10種DATA、HEADERS、PRIORITY 、RST_STREAM、SETTINGS、PUSH_PROMISE、PING、GOAWAY、WINDOW_UPDATE、CONTINUATION

多路復(fù)用Multiplexing
- 在一個(gè)TCP連接里,可以發(fā)送多個(gè)請(qǐng)求或回應(yīng),可以不按照順序發(fā)送

Multiplexing 在一個(gè)TCP連接里,服務(wù)器同時(shí)收到了A請(qǐng)求和B請(qǐng)求,于是先回應(yīng)A請(qǐng)求,結(jié)果發(fā)現(xiàn)處理過(guò)程非常耗時(shí),于是就發(fā)送A請(qǐng)求已經(jīng)處理好的部分,接著回應(yīng)B請(qǐng)求,完成后,再發(fā)送A請(qǐng)求剩下的部分。 ——
數(shù)據(jù)流

- 每個(gè)請(qǐng)求或回應(yīng)的數(shù)據(jù)包為一個(gè)流
- 每個(gè)流都會(huì)有一個(gè)StreamID,由啟動(dòng)流的終端分配
- 客戶端可以定義流的并發(fā)量
優(yōu)先級(jí)和依賴性

- 每個(gè)的幀頭都會(huì)包含流的優(yōu)先級(jí)標(biāo)識(shí)
- 可以根據(jù)優(yōu)先級(jí)幀來(lái)調(diào)整已經(jīng)發(fā)送的流的優(yōu)先級(jí)
- 沒(méi)有明確指定使用默認(rèn)值
- 流可以顯示依賴其他流
頭壓縮 HPack
- HTTP屬于無(wú)狀態(tài)協(xié)議,表示每次請(qǐng)求都會(huì)攜帶相同的信息,為了減少冗余信息使用了HPACK機(jī)制來(lái)對(duì)請(qǐng)求頭進(jìn)行壓縮
- 使用了默認(rèn)的Static Table 和 可以由客戶端添加字段的Dynamic Table
- 使用哈夫曼編碼
- 壓縮效率高效
- RFC 7541
中斷請(qǐng)求
- 如果想取消一個(gè)請(qǐng)求只需要發(fā)送RST_STREAM 幀就可以了
服務(wù)器推送
- 可以在沒(méi)有請(qǐng)求的情況下主動(dòng)向客戶端推送內(nèi)容
- 客戶端可以選擇是否中斷推送
ServerPush-1294
HTTP連接管理
HTTP/2連接是永久性的。為了最佳的性能,它期待直到確定與服務(wù)端的進(jìn)一步溝通不再必要的時(shí)候,客戶端才會(huì)關(guān)閉連接(例如,當(dāng)用戶導(dǎo)航到其他特定的網(wǎng)頁(yè)),或者直到服務(wù)端關(guān)閉連接。
Chrome Debug
使用Node.js 搭建一個(gè)建議HTTP2服務(wù)器
https://github.com/molnarg/node-http2-
使用Developer Tools來(lái)查看HTTP與HTTP/2的區(qū)別
可以看出HTTP/2使用一條TCP連接完成所有的資源請(qǐng)求
查看HTTP/2的建立與幀傳輸
chrome://net-internals/#http2WireShark也支持抓包,不過(guò)因?yàn)镠TTP/2走了TLS,所以要做一些代理處理,不做解釋。
Mobie
iOS
NSURLSession
- NSURLSession在iOS9.0之支持HTTP/2,SYPD
- 開(kāi)發(fā)者不需做修改
- iOS10之后支持調(diào)試可查看請(qǐng)求使用的協(xié)議
- 推測(cè)通過(guò)NSURLSession通過(guò)curl實(shí)現(xiàn)HTTP2...(經(jīng)過(guò)ida拆解只找到使用了和curl相同的HTTP/2頭解析庫(kù)??)
ASPN

- New provider API
- ASPN服務(wù)使用HTTP/2來(lái)實(shí)現(xiàn),通過(guò)減少TCP連接大幅度提升服務(wù)器效率,減少服務(wù)端壓力
總結(jié)
iOS同學(xué)基本上,如果使用了URLSession去做網(wǎng)絡(luò)請(qǐng)求可以啥都不用干,只要Server支持HTTP/2就可以了
Android
沒(méi)有寫過(guò)安卓...本部分僅參考
OKHttp
- 安卓端的一個(gè)HTTP的實(shí)現(xiàn)
- JAVA實(shí)現(xiàn)了HTTP/2
- 據(jù)Android同學(xué)SK IMSK 分享,該庫(kù)在重用TCP方面做的非常好

REF
http://kamranahmed.info/blog/2016/08/13/http-in-depth/ HTTP協(xié)議簡(jiǎn)介
https://github.com/square/okhttp 安卓Http網(wǎng)絡(luò)請(qǐng)求的實(shí)現(xiàn)
https://github.com/kylef/hpack.swift hpackSwift實(shí)現(xiàn)
https://github.com/curl/curl libcurl
https://github.com/nghttp2/nghttp2 curl里HPack的實(shí)現(xiàn)
https://github.com/apple/swift-corelibs-foundation Swift版本Foundation實(shí)現(xiàn)
http://opensource.apple.com/source/CF/CF-1153.18/
https://http2.github.io/
http://httpwg.org/specs/rfc7540.html RFC7540 HTTP2.0詳細(xì)實(shí)現(xiàn)
http://www.chromium.org/spdy/spdy-whitepaper
https://developer.apple.com/videos/play/wwdc2016/711/ NSURLSession: New Features and Best Practices
https://developer.apple.com/videos/play/wwdc2015/711/ Networking with NSURLSession
https://developer.apple.com/videos/play/wwdc2015/720/ What’s New in Notifications
https://developer.apple.com/videos/play/wwdc2015/724/
What’s New in Apple Push Notification Service


