一、WebSocket應用場景
通俗的講,WebSocket 是一種服務器可以主動向客戶端推送資訊,客戶端也可以主動向服務器發送資訊,實作真正的雙向平等對話的協議, WebSocket是為了解決HTTP的短鏈接而產生的一種協議,如果不與http客戶端產生關系,那么直接用TCP協議即可,無需使用WebSocket協議,
所以,在web客戶端如果實作雙向通信,想要服務端主動往web客戶端推送訊息的話,可以考慮使用websocket技術,
二、WebSocket原理
WebSocet是借用了一層HTTP協議,又對TCP協議進一步封裝而成的一種協議,
WebSocket是基于HTTP協議的,借用HTTP協議來完成了一部分握手動作,我們看websocket的請求頭:

我們著重看請求頭的這兩行:
Upgrade: websocket
Connection: Upgrade
這兩行是WebSocket的關鍵,通過這兩行資訊,告訴Apache、Nginx等http服務器,此協議要用WebSocket技術處理,而不是用HTTP協議處理,WebSocket技術誕生于2008年,至今大多數HTTP服務器已經支持了該協議,由此可見,WebSocket先通過HTTP協議與服務器建立聯系,然后通知HTTP服務器,要按照WebSocket協議來處理,至此,客戶端和服務端就建立了WebSocket長連接,
Sec-WebSocket-Key 是一個 Base64 encode 的值,這個是瀏覽器隨機生成的,是會話的唯一標識,
我們再看服務器對WebSocket請求的回應:

這里就是HTTP協議負責的最后區域,告訴客戶端,已經成功切換為WebSocket協議了,
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept 這個則是經過服務器確認,并且加密過后的 Sec-WebSocket-Key ,作為身份認證使用,
至此,HTTP 已經完成它所有作業了,接下來就是完全按照 WebSocket 協議進行了,
三、WebSocket特點
- 建立在 TCP 協議之上,服務器端的實作比較容易,
- 與 HTTP 協議有著良好的兼容性,默認埠也是80和443,并且握手階段采用 HTTP 協議,因此握手時不容易屏蔽,能通過各種 HTTP代理服務器,
- 資料格式比較輕量,性能開銷小,通信高效,
- 可以發送文本,也可以發送二進制資料,
- 沒有同源限制,客戶端可以與任意服務器通信,
- 協議識別符號是ws(如果加密,則為wss),服務器網址就是 URL,
四、與HTTP協議區別
Websocket 其實是一個新協議,跟 HTTP 協議基本沒有關系,只是為了兼容現有瀏覽器,所以在握手階段使用了 HTTP ,
http協議是短鏈接,因為請求之后,都會關閉連接,下次重新請求資料,需要再次打開連接,WebSocket協議是一種長連接,只需要通過一次請求來初始化鏈接,然后所有的請求和回應都是通過這個TCP鏈接進行通信,

五、心跳機制
WebSocket是基于TCP協議的,TCP協議自帶keepalive心跳機制,所以WebSocket也有keepalive心跳機制,
TCP的keepalive機制,我們后面研究,使用WebSocket技術,一般我們要自己實作心跳機制,那為什么不直接用TCP的keepalive機制呢,原因如下:
1.client例外掛死,此時keepalive機制無法反饋真實的client狀態;
2.client 例外斷電斷網出現TCP假死keepalive并不能根本性解決問題,實際上互聯網環境很不穩定;3.ws在應用層,基于傳輸層,在ws中操作TCP也很不方便,封裝就意味著易用性提高靈活性降低,
所以我們在應用層開啟心跳,(上面的原因,我們在研究TCP的keepalive后再做體會),應用層頻率為1次/10mins,
六、斷開重連處理機制
客戶端正常/例外斷開處理機制:

服務端正常/例外斷開處理機制:

server斷電斷網時client如何感知:

補充一下中間線路斷網情況:
如:中間nat設備斷網(互聯網環境中間nat設備是非常多的)或者server網路斷開.這里大家注意client斷網不算是中間線路斷網,因為client端斷網應用程式馬上可以感知.但是client所在局域網的出口nat斷開的就算是中間網路斷開.
其實上邊已經提到了server網路斷開的情況,分別說明了server和client各自的檢測辦法.但是很多網路不穩定的情況,如:斷開18分鐘后網路又恢復了,這里涉及到一個重連機制,首先大家要明白當中間網路斷開時實際上是兩段各自維護本端tcp的.最侄訓觸發tcp強制拆鏈(不發送四次揮手).分為兩種情況討論:
(1)網路恢復時,client已經將自己連接斷開了,但是server認為網路還在連接中,和tcp假死很像.這種情況在服務端檢測心跳超時之前,服務端推送訊息是沒有辦法到達客戶端的.但是這時服務端的試圖發訊息動作會觸發服務端發現這個連接已經斷開了. 從現象看ws重連時間為: 網路恢復時間——>server發現連接斷開(server發訊息)+超時/server心跳檢測超時 (前提:網路斷開后到網路恢復中間這段時間server沒法過訊息給client,如果發送過可能網路連接上立即觸發服務端發現連接斷開.)
(2)網路恢復時,client沒有將自己連接斷開,但是server已經斷開.這種情況在client下一次心跳發送后會觸發tcp重發,重發一定時間沒有回復client也會進行強制拆鏈.ws重連時間為:網路恢復時間——>client下一次心跳時間+超時. (前提:網路斷開后到網路恢復中間這段時間client沒發過心跳給server,如果發送過可能網路連接上立即觸發客戶端發現連接斷開.)
上邊兩個前提有點難懂,意思是當網路斷開到網路恢復中間這段時間發送過訊息,那么這個訊息第一次發送肯定是到不了對端,但是這時就已經開始tcp重傳機制了,可能網路恢復時恰好有一次重傳,你的訊息可以發到對端了,但是對端tcp埠已經關閉,tcp發生例外也就立即觸發了本端tcp的關閉.
綜上:tcp重連是需要時間的,這個時間肯定是越短越好,但是又不能太短,這個時間的確定大家可以參考本篇最后的測驗.
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/300712.html
標籤:其他
