websocket原理、爲什麼能實現持久鏈接?

WebSocket 是 HTML5 一種新的協議。它實現了瀏覽器與服務器全雙工通訊,能更好的節省服務器資源和帶寬並達到實時通信它創建在 TCP 之上,同 HTTP 同樣經過 TCP 來傳輸數據,可是它和 HTTP 最大不一樣是:web

  • WebSocket 是一種雙向通訊協議,在創建鏈接後,WebSocket 服務器和 Browser/Client Agent 都能主動的向對方發送或接收數據,就像 Socket 同樣;
  • WebSocket 須要相似 TCP 的客戶端和服務器端經過握手鍊接,鏈接成功後才能相互通訊。

Websocket是一種在單個TCP鏈接上進行全雙工通信的協議,在Websocket協議中,客戶端和服務端只須要作一個握手的動做,就能造成一條通道,二者之間能夠進行數據互相傳送。ajax

因此WebSocket協議分爲兩部分:瀏覽器

  1. 握手
  2. 數據傳輸 

握手

客戶端發送一個請求服務器

GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: example.com
Origin: null
Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ==
Sec-WebSocket-Version: 13

能夠看到,客戶端發起的 WebSocket 鏈接報文相似傳統 HTTP 報文,」Upgrade:websocket」參數值代表這是 WebSocket 類型請求,「Sec-WebSocket-Key」是 WebSocket 客戶端發送的一個 base64 編碼的密文,要求服務端必須返回一個對應加密的「Sec-WebSocket-Accept」應答,不然客戶端會拋出「Error during WebSocket handshake」錯誤,並關閉鏈接。websocket

服務端收到報文後返回的數據格式相似:socket

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: fFBooB7FAkLlXgRSz0BT3v4hq5s=
Sec-WebSocket-Origin: null
Sec-WebSocket-Location: ws://example.com/

收到這一段響應後,客戶端須要比對Sec-WebSocket-Accept值,這個值表示服務器贊成握手創建鏈接,是客戶端傳輸過來的Sec-WebSocket-Key跟「258EAFA5-E914-47DA-95CA-C5AB0DC85B11」拼接後,用SHA-1加密,並進行BASE-64編碼得來的。ide

客戶端收到Sec-WebSocket-Accept後,將本地的Sec-WebSocket-Key進行一樣的編碼,而後比對。編碼

只須要通過一次HTTP請求,就能夠作到源源不斷的信息傳送了。(在程序設計中,這種設計叫作回調,即:你有信息了再來通知我,而不是我傻乎乎的每次跑來問你)
這樣的協議解決了上面同步有延遲,並且還很是消耗資源的這種狀況。加密

在傳統的方式上,要不斷的創建,關閉HTTP協議,因爲HTTP是非狀態性的,每次都要 從新傳輸identity info(鑑別信息),來告訴服務端你是誰。
可是 Websocket只須要一次HTTP握手,因此說整個通信過程是創建在一次鏈接/狀態中,也就避免了HTTP的非狀態性,服務端會一直知道你的信息,直到你關閉請求,這樣就解決了接線員要反覆解析HTTP協議,還要查看identity info的信息。
HTTP協議的另一個特色, 被動性。
何爲被動性呢,其實就是,服務端不能主動聯繫客戶端,只能有客戶端發起。
同時由 客戶主動詢問,轉換爲 服務器(推送)有信息的時候就發送(固然客戶端仍是等主動發送信息過來的。。),沒有信息的時候就交給接線員(Nginx),不須要佔用自己速度就慢的 客服(Handler)
--------------------
至於怎麼在不支持Websocket的客戶端上使用Websocket。。答案是: 不能
可是能夠經過上面說的 long poll 和 ajax 輪詢來 模擬出相似的效果 -----
相關文章
相關標籤/搜索