WebSocket實現與原理

概述 

       傳統的HTTP協議是無狀態的,每次請求(request)都要由客戶端(如 瀏覽器)主動發起,服務端進行處理後返回response結果,而服務端很難主動向客戶端發送數據;這種客戶端是主動方,服務端是被動方的傳統Web模式 對於信息變化不頻繁的Web應用來說造成的麻煩較小,而對於涉及實時信息的Web應用卻帶來了很大的不便,如帶有即時通信、實時數據、訂閱推送等功能的應 用。在WebSocket規範提出之前,開發人員若要實現這些實時性較強的功能,經常會使用折衷的解決方法:輪詢(polling)和Comet技術。其實後者本質上也是一種輪詢,只不過有所改進。

       輪詢是最原始的實現實時Web應用的解決方案。輪詢技術要求客戶端以設定的時間間隔週期性地向服務端發送請求,頻繁地查詢是否有新的數據改動。明顯地,這種方法會導致過多不必要的請求,浪費流量和服務器資源。

    Comet技術又可以分爲長輪詢和流技術。長輪詢改進了上述的輪詢技術,減小了無用的請求。它會爲某些數據設定過期時間,當數據過期後纔會向服務端發送請求;這種機制適合數據的改動不是特別頻繁的情況。流技術通常是指客戶端使用一個隱藏的窗口與服務端建立一個HTTP長連接,服務端會不斷更新連接狀態以保持HTTP長連接存活;這樣的話,服務端就可以通過這條長連接主動將數據發送給客戶端;流技術在大併發環境下,可能會考驗到服務端的性能。

Http長連接與Websocket區別

       HTTP1.1通過使用Connection:keep-alive進行長連接,HTTP 1.1默認進行持久連接。在一次 TCP 連接中可以完成多個 HTTP 請求,但是對每個請求仍然要單獨發 header,Keep-Alive不會永久保持連接,它有一個保持時間,可以在不同的服務器軟件(如Apache)中設定這個時間。這種長連接是一種“僞鏈接”

       websocket的長連接,是一個真的全雙工。長連接第一次tcp鏈路建立之後,後續數據可以雙方都進行發送,不需要發送請求頭。

       keep-alive雙方並沒有建立正真的連接會話,服務端可以在任何一次請求完成後關閉。WebSocket 它本身就規定了是正真的、雙工的長連接,兩邊都必須要維持住連接的狀態。

 

WebSocket流程

        Websocket是html5提出的一個協議規範,是爲解決客戶端與服務端實時通信。本質上是一個基於tcp,先通過HTTP/HTTPS協議發起一條特殊的http請求進行握手後創建一個用於交換數據的TCP連接。WebSocket優勢: 瀏覽器和服務器只需要要做一個握手的動作,在建立連接之後,雙方可以在任意時刻,相互推送信息。同時,服務器與客戶端之間交換的頭信息很小。

首先,WebSocket連接必須由瀏覽器發起,因爲請求協議是一個標準的HTTP請求,格式如下:

GET ws://localhost:3000/ws/chat HTTP/1.1
Host: localhost
Upgrade: websocket
Connection: Upgrade
Origin: http://localhost:3000
Sec-WebSocket-Key: client-random-string
Sec-WebSocket-Version: 13

該請求和普通的HTTP請求有幾點不同:

GET請求的地址不是類似/path/,而是以ws://開頭的地址;
請求頭Upgrade: websocket和Connection: Upgrade表示這個連接將要被轉換爲WebSocket連接;
Sec-WebSocket-Key是用於標識這個連接,並非用於加密數據;
Sec-WebSocket-Version指定了WebSocket的協議版本。

 

隨後,服務器如果接受該請求,就會返回如下響應:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: server-random-string

該響應代碼101表示本次連接的HTTP協議即將被更改,更改後的協議就是Upgrade: websocket指定的WebSocket協議。

版本號和子協議規定了雙方能理解的數據格式,以及是否支持壓縮等等。如果僅使用WebSocket的API,就不需要關心這些。

現在,一個WebSocket連接就建立成功,瀏覽器和服務器就可以隨時主動發送消息給對方。消息有兩種,一種是文本,一種是二進制數據。通常,我們可以發送JSON格式的文本,這樣,在瀏覽器處理起來就十分容易。

爲什麼WebSocket連接可以實現全雙工通信而HTTP連接不行呢?實際上HTTP協議是建立在TCP協議之上的,TCP協議本身就實現了全雙工通信,但是HTTP協議的請求-應答機制限制了全雙工通信。WebSocket連接建立以後,其實只是簡單規定了一下:接下來,咱們通信就不使用HTTP協議了,直接互相發數據吧。

安全的WebSocket連接機制和HTTPS類似。首先,瀏覽器用wss://xxx創建WebSocket連接時,會先通過HTTPS創建安全的連接,然後,該HTTPS連接升級爲WebSocket連接,底層通信走的仍然是安全的SSL/TLS協議。

 

WebSocket支持的瀏覽器

  • Chrome
  • Firefox
  • IE >= 10
  • Sarafi >= 6
  • Android >= 4.4
  • iOS >= 8

 

Springboot的WebSocket實現

springboot已經整合了websocket,直接引入包就可以了.實在沒什麼寫的.

		<dependency>  
           <groupId>org.springframework.boot</groupId>  
           <artifactId>spring-boot-starter-websocket</artifactId>  
       </dependency> 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章