標籤:接收 錯誤 bullet 協議 佔用 而不是 最大 base 雙向
WebSocket 是 HTML5 一種新的協議。它實現了瀏覽器與伺服器全雙工系統通訊,能更好的節省伺服器資源和頻寬並達到即時通訊,它建立在 TCP 之上,同 HTTP 一樣通過 TCP 來傳輸資料,但是它和 HTTP 最大不同是:
- WebSocket 是一種雙向通訊協定,在建立串連後,WebSocket 伺服器和 Browser/Client Agent 都能主動的向對方發送或接收資料,就像 Socket 一樣;
- WebSocket 需要類似 TCP 的用戶端和伺服器端通過握手串連,串連成功後才能相互連信。
Websocket是一種在單個TCP串連上進行全雙工系統通訊的協議,在Websocket協議中,用戶端和服務端只需要做一個握手的動作,就能形成一條通道,兩者之間可以進行資料互相傳送。
所以WebSocket協議分為兩部分:
- 握手
- 資料轉送
握手
用戶端發送一個請求
GET / HTTP/1.1Upgrade: websocketConnection: UpgradeHost: example.comOrigin: nullSec-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”錯誤,並關閉串連。
服務端收到報文後返回的資料格式類似:
HTTP/1.1 101 Switching ProtocolsUpgrade: websocketConnection: UpgradeSec-WebSocket-Accept: fFBooB7FAkLlXgRSz0BT3v4hq5s=Sec-WebSocket-Origin: nullSec-WebSocket-Location: ws://example.com/
收到這一段響應後,用戶端需要比對Sec-WebSocket-Accept值,這個值表示伺服器同意握手建立串連,是用戶端傳輸過來的Sec-WebSocket-Key跟“258EAFA5-E914-47DA-95CA-C5AB0DC85B11”拼接後,用SHA-1加密,並進行BASE-64編碼得來的。
用戶端收到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 輪詢來
類比出類似的效果
-----
websocket原理、為何能實現持久串連?