圖解HTTP九:基於 HTTP 的功能追加協議

9.1 基於 HTTP 的協議

HTTP 功能上的不足可通過創建一套全新的協議來彌補。可是目前基於 HTTP 的 Web 瀏覽器的使用環境已遍佈全球,因此無法完全拋棄 HTTP。有一些新協議的規則是基於 HTTP 的,並在此基礎上添加了新的功能。

9.2 消除 HTTP 瓶頸的 SPDY

Google 在 2010 年發佈了 SPDY(取自 SPeeDY,發音同 speedy),其開發目標旨在解決 HTTP 的性能瓶頸,縮短 Web 頁面的加載時間(50%)。

9.2.1 HTTP 的瓶頸

爲了儘可能實時地顯示這些更新的內容,服務器上一有內容更新,就需要直接把那些內容反饋到客戶端的界面上。雖然看起來挺簡單的,但 HTTP 卻無法妥善地處理好這項任務。使用 HTTP 協議探知服務器上是否有內容更新,就必須頻繁地從客戶端到服務器端進行確認。如果服務器上沒有內容更新,那麼就會產生徒勞的通信。若想在現有 Web 實現所需的功能,以下這些 HTTP 標準就會成爲瓶頸。

  • 一條連接上只可發送一個請求。
  • 請求只能從客戶端開始。客戶端不可以接收除響應以外的指令。
  • 請求 / 響應首部未經壓縮就發送。首部信息越多延遲越大。
  • 發送冗長的首部。每次互相發送相同的首部造成的浪費較多。
  • 可任意選擇數據壓縮格式。非強制壓縮發送。
    在這裏插入圖片描述
以前的 HTTP 通信

Ajax 的解決方法
Ajax(Asynchronous JavaScript and XML, 異 步 JavaScript 與 XML 技術)是一種有效利用JavaScript 和 DOM(Document Object Model,文檔對象模型)的操作,以達到局部 Web 頁面替換加載的異步通信手段。和以前的同步通信相比,由於它只更新一部分頁面,響應中傳輸的數據量會因此而減少,這一優點顯而易見。Ajax 的核心技術是名爲 XMLHttpRequest 的 API,通過 JavaScript 腳本語言的調用就能和服務器進行 HTTP 通信。藉由這種手段,就能從已加載完畢的 Web 頁面上發起請求,只更新局部頁面。而利用 Ajax 實時地從服務器獲取內容,有可能會導致大量請求產生。另外, Ajax 仍未解決 HTTP 協議本身存在的問題。
在這裏插入圖片描述

Ajax 通信

Comet 的解決方法
一旦服務器端有內容更新了, Comet 不會讓請求等待,而是直接給客戶端返回響應。這是一種通過延遲應答,模擬實現服務器端向客戶端推送(Server Push)的功能。通常,服務器端接收到請求,在處理完畢後就會立即返回響應,但爲了實現推送功能, Comet 會先將響應置於掛起狀態,當服務器端有內容更新時,再返回該響應。因此,服務器端一旦有更新,就可以立即反饋給客戶端。內容上雖然可以做到實時更新,但爲了保留響應,一次連接的持續時間也變長了。期間,爲了維持連接會消耗更多的資源。另外, Comet 也仍未解決 HTTP 協議本身存在的問題。

在這裏插入圖片描述

Comet 通信

SPDY 的目標
陸續出現的 Ajax 和 Comet 等提高易用性的技術,一定程度上使 HTTP 得到了改善,但 HTTP 協議本身的限制也令人有些束手無策。爲了進行根本性的改善,需要有一些協議層面上的改動。處於持續開發狀態中的 SPDY 協議,正是爲了在協議級別消除 HTTP 所遭遇的瓶頸。

9.2.2 SPDY 的設計與功能

SPDY 沒有完全改寫 HTTP 協議,而是在 TCP/IP 的應用層與運輸層之間通過新加會話層的形式運作。同時,考慮到安全性問題, SPDY 規定通信中使用 SSL。SPDY 以會話層的形式加入,控制對數據的流動,但還是採用 HTTP 建立通信連接。因此,可照常使用 HTTP 的 GET 和 POST 等方 法、 Cookie 以及 HTTP 報文等。

SPDY 的設計

使用 SPDY 後, HTTP 協議額外獲得以下功能。
多路複用流
通過單一的 TCP 連接,可以無限制處理多個 HTTP 請求。所有請求的處理都在一條 TCP 連接上完成,因此TCP 的處理效率得到提高。
賦予請求優先級
SPDY 不僅可以無限制地併發處理請求,還可以給請求逐個分配優先級順序。這樣主要是爲了在發送多個請求時,解決因帶寬低而導致響應變慢的問題。
壓縮 HTTP 首部
壓縮 HTTP 請求和響應的首部。這樣一來,通信產生的數據包數量和發送的字節數就更少了。
推送功能
支持服務器主動向客戶端推送數據的功能。這樣,服務器可直接發送數據,而不必等待客戶端的請求。
服務器提示功能
服務器可以主動提示客戶端請求所需的資源。由於在客戶端發現資源之前就可以獲知資源的存在,因此在資源已緩存等情況下,可以避免發送不必要的請求。

9.2.3 SPDY 消除 Web 瓶頸了嗎

希望使用 SPDY 時, Web 的內容端不必做什麼特別改動,而 Web 瀏覽器及 Web 服務器都要爲對應 SPDY做出一定程度上的改動。有好幾家 Web 瀏覽器已經針對 SPDY 做出了相應的調整。另外, Web 服務器也進行了實驗性質的應用,但把該技術導入實際的 Web 網站卻進展不佳。因爲 SPDY 基本上只是將單個域名( IP 地址)的通信多路複用,所以當一個 Web 網站上使用多個域名下的資源,改善效果就會受到限制。SPDY 的確是一種可有效消除 HTTP 瓶頸的技術,但很多 Web 網站存在的問題並非僅僅是由 HTTP 瓶頸所導致。對 Web 本身的速度提升,還應該從其他可細緻鑽研的地方入手,比如改善 Web 內容的編寫方式等。

9.3 使用瀏覽器進行全雙工通信的 WebSocket

9.3.1 WebSocket 的設計與功能

WebSocket,即 Web 瀏覽器與 Web 服務器之間全雙工通信標準。

9.3.2 WebSocket 協議

一旦 Web 服務器與客戶端之間建立起 WebSocket 協議的通信連接,之後所有的通信都依靠這個專用協議進行。通信過程中可互相發送 JSON、 XML、 HTML 或圖片等任意格式的數據。由於是建立在 HTTP 基礎上的協議,因此連接的發起方仍是客戶端,而一旦確立 WebSocket 通信連接,不論服務器還是客戶端,任意一方都可直接向對方發送報文。下面我們列舉一下 WebSocket 協議的主要特點。

推送功能
支持由服務器向客戶端推送數據的推送功能。這樣,服務器可直接發送數據,而不必等待客戶端的請求。
減少通信量
只要建立起 WebSocket 連接,就希望一直保持連接狀態。和 HTTP 相比,不但每次連接時的總開銷減少,而且由於 WebSocket 的首部信息很小,通信量也相應減少了。

爲了實現 WebSocket 通信,在 HTTP 連接建立之後,需要完成一次“握手”(Handshaking)的步驟。

  • 握手·請求:爲了實現 WebSocket 通信,需要用到 HTTP 的 Upgrade 首部字段,告知服務器通信協議發生改變,以達到握手的目的。

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

Sec-WebSocket-Key 字段內記錄着握手過程中必不可少的鍵值。 Sec-WebSocket-Protocol 字段內記錄
使用的子協議。子協議按 WebSocket 協議標準在連接分開使用時,定義那些連接的名稱。

  • 握手·響應:對於之前的請求,返回狀態碼 101 Switching Protocols 的響應。

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat

Sec-WebSocket-Accept 的字段值是由握手請求中的 Sec-WebSocket-Key 的字段值生成的。成功握手確立 WebSocket 連接之後,通信時不再使用 HTTP 的數據幀,而採用 WebSocket 獨立的數據幀。
在這裏插入圖片描述

WebSocket 通信

  • WebSocket API
    JavaScript 可調用“The WebSocket API”(http://www.w3.org/TR/websockets/,由 W3C 標準制定)內提
    供的 WebSocket 程序接口,以實現 WebSocket 協議下全雙工通信。以下爲調用 WebSocket API,每 50ms 發送一次數據的實例。

var socket = new WebSocket(‘ws://game.example.com:12010/updates’);
socket.onopen = function () {
setInterval(function() {
if (socket.bufferedAmount == 0)
socket.send(getUpdateData());
}, 50);
};

9.4 Web 服務器管理文件的 WebDAV

WebDAV(Web-based Distributed Authoring and Versioning,基於萬維網的分佈式創作和版本控制)是一個可對 Web 服務器上的內容直接進行文件複製、編輯等操作的分佈式文件系統。除了創建、刪除文件等基本功能,它還具備文件創建者管理、文件編輯過程中禁止其他用戶內容覆蓋的加鎖功能,以及對文件內容修改的版本控制功能。
在這裏插入圖片描述

WebDAV

使用 HTTP/1.1 的 PUT 方法和 DELETE 方法,就可以對 Web 服務器上的文件進行創建和刪除操作。可是出於安全性及便捷性等考慮,一般不使用。

9.5.1 擴展 HTTP/1.1 的 WebDAV

在這裏插入圖片描述

WebDAV 擴展的概念

  • 集合( Collection):是一種統一管理多個資源的概念。以集合爲單位可進行各種操作。也可實現類似集合的集合這樣的疊加。
  • 資源( Resource):把文件或集合稱爲資源。
  • 屬性( Property):定義資源的屬性。定義以“名稱 = 值”的格式執行。
  • 鎖( Lock):把文件設置成無法編輯狀態。多人同時編輯時,可防止在同一時間進行內容寫入。

9.5.2 WebDAV 內新增的方法及狀態碼

WebDAV 爲實現遠程文件管理,向 HTTP/1.1 中追加了以下這些方法。

  • PROPFIND :獲取屬性
  • PROPPATCH :修改屬性
  • MKCOL :創建集合
  • COPY :複製資源及屬性
  • MOVE :移動資源
  • LOCK :資源加鎖
  • UNLOCK :資源解鎖

爲配合擴展的方法,狀態碼也隨之擴展。

  • 102 Processing :可正常處理請求,但目前是處理中狀態
  • 207 Multi-Status :存在多種狀態
  • 422 Unprocessible Entity :格式正確,內容有誤
  • 423 Locked :資源已被加鎖
  • 424 Failed Dependency :處理與某請求關聯的請求失敗,因此不再維持依賴關係
  • 507 Insufficient Storage :保存空間不足
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章