websocket原理、為何能實現持久連接?


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

  • WebSocket 是一種雙向通信協議,在建立連接后,WebSocket 服務器和 Browser/Client Agent 都能主動的向對方發送或接收數據,就像 Socket 一樣;
  • WebSocket 需要類似 TCP 的客戶端和服務器端通過握手連接,連接成功后才能相互通信。

Websocket是一種在單個TCP連接上進行全雙工通訊的協議,在Websocket協議中,客戶端和服務端只需要做一個握手的動作,就能形成一條通道,兩者之間可以進行數據互相傳送。

所以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”錯誤,並關閉連接。

服務端收到報文后返回的數據格式類似:

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編碼得來的。

客戶端收到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 輪詢來 模擬出類似的效果
-----

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM