WebSocket 是一種基于 TCP 連接上進行全雙工通信的協議,相對于 HTTP 這種非持久的協議來說,WebSocket 是一個持久化網路通信的協議,

WebSocket 是一種基于 TCP 連接上進行全雙工通信的協議,相對于 HTTP 這種非持久的協議來說,WebSocket 是一個持久化網路通信的協議,
它不僅可以實作客戶端請求服務器,同時可以允許服務端主動向客戶端推送資料,在 WebSocket API 中,客戶端和服務器只需要完成一次握手,兩者之間就直接可以創建持久性的連接,并進行雙向資料傳輸,
為什么需要 WebSocket
在 Web 應用架構中,連接由 HTTP/1.0 和 HTTP/1.1 處理,HTTP 是客戶端/服務器模式中 請求一回應 所用的協議,在這種模式中,客戶端(一般是瀏覽器)向服務器提交 HTTP 請求,服務器回應請求的資源(例如 HTML 頁面),
HTTP 是無狀態的,也就是說,它將每個請求當成唯一和獨立的,無狀態協議具有一些優勢,例如,服務器不需要保存有關會話的資訊,從而不需要存盤資料,但是,這也意味著在每次 HTTP 請求和回應中都會發送關于請求的冗余資訊,比如使用 Cookie 進行用戶狀態的驗證,
隨著客戶端和服務器之間互動的增加,HTTP 協議在客戶端和服務器之間通信所需要的資訊量快速增加,
從根本上講,HTTP 還是 半雙工 的協議,也就是說,在同一時刻資訊的流向只能單向的:客戶端向服務器發送請求(單向),然后服務器回應請求(單向),半雙工方式的通信效率是非常低的,
同時 HTTP 協議有一個缺陷:通信只能由客戶端發起,
這種單向請求的特點,注定了如果服務器有狀態變化,是無法主動通知客戶端的,
為了能夠及時的獲取服務器的變化,我們嘗試過各種各樣的方式:
- 輪詢(polling):每隔一段時間,就發出一個請求,了解服務器有沒有新的資訊,不精準,有延時,大量無效資料交換,
- 長輪詢( long polling):客戶端向服務器請求資訊,并在設定的時間段內保持連接,直到服務器有新訊息回應,或者連接超時,這種技術常常稱作“掛起GET”或“擱置POST”,占用服務器資源,相對輪詢并沒有優勢,沒有標準化,
- 流化技術:在流化技術中,客戶端發送一個請求,服務器發送并維護一個持續更新和保持打開(可以是無限或者規定的時間段)的開放回應,每當服務器有需要交付給客戶端的資訊時,它就更新回應,服務器從不發出完成 HTTP 回應,代理和防火墻可能快取回應,導致資訊交付的延遲增加,
上述方法提供了近乎實時的通信,但是它們也涉及 HTTP 請求和回應首標,包含了許多附加和不必要的首標資料與延遲,此外,在每一種情況下,客戶端都必須等待請求回傳,才能發出后續的請求,而這顯著地增加了延退,同時也極大地增加了服務器的壓力,
什么是 WebSocket
而 Websocket 是一種自然的全雙工、雙向、單套接字連接,解決了 HTTP 協議中不適合于實時通信的問題,2008 年被提出,2011 年成為國際標準,
Websocket 協議能夠通過 Web 進行客戶端和服務器之間的全雙工通信,并支持二進制資料和文本字串的傳輸,
這個協議由開始的握手和之后的基本訊息框架組成,是建立在 TCP 協議上的,相比于 HTTP 協議,Websocket 鏈接一旦建立,即可進行雙向的實時通信,

其特點包括:
(1)建立在 TCP 協議之上,服務器端的實作比較容易,
(2)與 HTTP 協議有著良好的兼容性,默認埠也是 80 和 443,并且握手階段采用 HTTP 協議,因此握手時不容易屏蔽,能通過各種 HTTP 代理服務器,
(3)資料格式比較輕量,性能開銷小,通信高效,
(4)可以發送文本,也可以發送二進制資料,
(5)沒有同源限制,客戶端可以與任意服務器通信,
相似技術
Server-sent Events(SSE):
https://www.ruanyifeng.com/blog/2017/05/server-sent_events.html
https://www.cnblogs.com/goloving/p/9196066.html
SPDY (讀作“SPeeDY”):已不再維護,由 HTTP/2 取代
https://baike.baidu.com/item/SPDY/3399551#7
WebRTC
https://baike.baidu.com/item/WebRTC/5522744
通信原理
WebSocket 鏈接是如何建立的?
前面說過,WebSocket 在握手階段采用的是 HTTP 協議,Websocket 借用了 HTTP 的一部分協議來完成一次握手,(HTTP的三次握手,此處只完成一次)
HTTP 請求與回應首部

WebSocket 請求與回應首部

鏈接通信模擬
HTTP 輪詢
首先是 ajax 輪詢,其原理非常簡單,讓瀏覽器隔個幾秒就發送一次請求,詢問服務器是否有新資訊,
場景再現:
- 客戶端:啦啦啦,有沒有新資訊(Request)
- 服務端:沒有(Request)
- 客戶端:啦啦啦,有沒有新資訊(Request)
- 服務端:沒有,,(Response)
- 客戶端:啦啦啦,有沒有新資訊(Request)
- 服務端:你好煩啊,沒有啊,,(Response)
- 客戶端:啦啦啦,有沒有新訊息(Request)
- 服務端:好啦好啦,有啦給你 ’ 西嶺真帥’ ,(Response)
- 客戶端:啦啦啦,有沒有新訊息(Request)
- 服務端:,,,沒,,,,沒,,沒有
從上面可以看出,輪詢其實就是在不斷地建立HTTP連接,然后等待服務端處理,可以體現 HTTP 協議的另外一個特點,被動性,同時,http 的每一次請求與回應結束后,服務器將客戶端資訊全部丟棄,下次請求,必須攜帶身份資訊(cookie),無狀態性,
WebSocket
客戶端通過 http(騎馬)帶著信請求服務器,但同時,攜帶了 Upgrade:websocket 和Connection:Upgrade(兩根管子),服務器如果支持 WebSocket 協議(有兩根管子的介面),使用 Websocket 協議回傳可用資訊(丟棄馬匹),此后資訊的傳遞,均使用這兩個管子,除非有一方人為的將管子切斷,若服務器不支持,客戶端請求鏈接失敗,回傳錯誤資訊,
Websocket 的出現,干凈利落的解決了這些問題,
所以上面的情景可以做如下修改,
- 客戶端:啦啦啦,我要建立 Websocket 協議,需要的服務:chat,Websocket協議版本:13(HTTP Request)
- 服務端:ok,確認,已升級為 Websocket協議(HTTP Protocols Switched)
- 客戶端:麻煩你有資訊的時候推送給我噢,,
- 服務端:ok,有的時候會告訴你的,
- 客戶端:balabala開始斗圖balabala
- 服務端:蒼*空bala
- 客戶端:流鼻血了,我擦……
- 服務端:哈哈哈牛XX啊哈哈哈哈
- 服務端:笑死我了哈哈
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/323293.html
標籤:其他
上一篇:Docker從入門到初步掌握
下一篇:hadoop集群拓撲配置
