👏作者簡介:大家好,我是愛寫博客的嗯哼,愛好Java的小菜鳥
🔥如果感覺博主的文章還不錯的話,請👍三連支持👍一下博主哦
📝個人博客:敬請期待
文章目錄
- 前言
- 一、關于HTTP
- 1. HTTP請求
- 2. 傳統輪詢
- 3. 長輪詢
- 二、關于WebSocket
- 1.WebSocket基礎
- 2. WebSocket請求流程
- 3. Websocket總結
- 三、總結
- 結語
前言
相信大家都對HTTP協議比較熟悉,因為它是我們接觸最多的一個協議。但Websocket跟它又有什么關系,有什么作用呢?這篇文章我們通過HTTP來引出Webscoket這個協議。
一、關于HTTP
1. HTTP請求
- OSI七層架構:
大家都知道,HTTP協議是基于TCP協議開發的一款應用層協議,它主要針對的就是網站的一些請求
- 請求圖:
像這種可以算的上HTTP最簡單的請求了,客戶端向服務器請求數據,此時服務器響應數據,根據客戶端請求的數據來返回對應的信息,可以進行一些基本的獲取信息、請求數據一類的請求。
當然根據REST規范,還有POST請求、PUT請求、HEAD請求,這里就不一一列舉了,大家有興趣可以自己查一下。
因為HTTP這種協議只能客戶端發送請求,服務器不能主動發送請求。大家看到這或許會有疑惑,為什么還要要求服務器主動推送呢。
- 普通請求:
普通請求結合Ajax代碼示例:
setInterval(function() {$.get("/to/hong", function(data, status) {console.log(data);});
}, 10000);
大家看這個圖就知道了,此時小明想向小紅炫耀一下自家的貓多么厲害(或許這就是孩童的樂趣吧),可是服務器并不能主動推送信息,小紅永遠也收不到,也就無法看到能后空翻的小貓了。
那么該如何解決這個問題呢?樂于助人的攻城獅想出了辦法:可以讓客戶端頻繁的去請求服務器不就行了,只要我請求的頻率到一定程度,不就和服務器主動推送沒區別了嗎。
2. 傳統輪詢
- 輪詢方式:
傳統輪詢請求結合Ajax代碼示例:
function poll() {setTimeout(function() {$.get("/path/to/server", function(data, status) {console.log(data);// 發起下一次請求poll();});}, 10000);
}
因為HTTP請求是請求響應類型的,所以每次HTTP請求之后都會返回數據,即使沒有信息,也會返回一個空值。
這樣對于聊天的話就會做很多無用的請求,讓服務器遭受“凌遲之痛”,并且消耗大量帶寬。
小明也很苦惱,明明就發一個消息,為什么消耗這么多流量呢?剛充的花費就沒了。樂于助人的攻城獅肯定不會眼睜睜的看著小明因為約會把自己的金錢全部掏空,于是就做了一個違背祖宗的決定。
3. 長輪詢
在上面的傳統輪詢中,巨量的請求都涌向服務器,占據大量網絡資源。那么如何才能改進,避免大量資源的占用呢?
長輪詢意味著瀏覽器只需啟動一個HTTP請求,其連接的服務器會“hold”住此次連接,直到有新消息才返回響應信息并關閉連接,客戶端處理完響應信息后再向服務器發送新的HTTP請求,以此類推。
- 輪詢示例:
跟上面的短輪詢對比,從圖片上就感覺到不是那么密密麻麻的了。網絡也是如此,減少了大量不必要的請求。
輪詢可能在以下3種情況時終止:
- 有新數據推送 。當服務器向瀏覽器推送信息后,應該主動結束程序運行從而讓連接斷開,這樣瀏覽器才能及時收到數據。
- 沒有新數據推送 。應該設定一個最長時限,避免WEB服務器超時(Timeout),若一直沒有新信息,服務器應主動向瀏覽器發送本次輪詢無新信息的正常響應,并斷開連接,這也被稱為“心跳”信息。
- 網絡故障或異常 。由于網絡故障等因素造成的請求超時或出錯也可能導致輪詢的意外中斷,此時瀏覽器將收到錯誤信息。
這時候小明才長長嘆拉口氣,終于不會把自己的小金庫花光了,還準備跟小紅約會的時候用呢。
- 注意:長輪詢和長連接是有區別的。長連接是基于TCP的,在協議上的修改,而長輪詢是編程掛起手動修改的
二、關于WebSocket
在上面你會發現,就算是HTTP的長輪詢也是基于請求-應答的這種半雙工通信模式,雖然可以雙向的收發數據,但一個時刻只能一個方向有動作,傳輸效率低。
最終要的一點就是,它是一種被動的通信模式,服務器只能被動的響應客戶端請求,無法主動發送數據。
做人不能總是主動,你越主動就越廉價。當然攻城獅也明白這個道理,為了讓小明的愛情更加美好,就開始想辦法做一個全雙工的通信模型,不用像HTTP一樣回合制類型那么客套了。于是,服務器就可以變得更加主動,一旦服務器有新的數據,就可以推送給小明,不需要再輪詢了,通訊效率也變高了。
1.WebSocket基礎
WebSocket采用了二進制幀結構,語法、語義跟HTTP完全不兼容,但現在的龍頭老大還是HTTP,于是就盡量的往HTTP靠攏。
服務發現方面,WebSocket沒有使用TCP的”IP地址+端口號",而是沿用了HTTP的URL格式,但開頭協議名不是http,而是ws和wss,默認端口也選擇了80和443。
ws://www.baidu.com:8080/server
這便是websocket的請求路徑,唯一不同的就是協議名
2. WebSocket請求流程
作為一個新星協議,它是如何建立連接的呢
- 建立連接:
從上面這個圖可以看出來,Websocket竟然和HTTP有關系,最上面的是HTTP1.1版本,使用的GET請求,其中請求頭一個字段很重要Upgrade,看這個意思大家應該都知道,是升級的意思。
這個請求就是使用HTTP請求向服務器傳達一個信息,我要開始轉換為WebSocket協議。
如果用啦HTTP請求那肯定會有一個響應,因為HTTP就是請求應答模型的,當然這次也肯定不例外。
- 連接響應:
上面這個就是服務端產生的應答,告訴客戶端,已經轉換成功,以后我們就可以用Websocket交流信息了(HTTP:就沒人管我的死活嗎?T﹏T)
那么websocket是如何工作的呢?
首先就是上面提到的建立連接,建立連接成功之后,就開始進行全雙工通信,這時服務端和客戶端就可以自由發送請求了。
websocket聊天示例:
小明:程序猿太厲害了吧,我以后也要成為一名程序猿
3. Websocket總結
WebSocket 是一種基于 TCP 協議的通信協議,它提供了全雙工的實時通信能力,使服務器和
客戶端之間可以進行雙向的、實時的數據傳輸。
以下是 WebSocket 的一些重要特點和用法:
-
雙向通信:WebSocket 允許服務器和客戶端之間進行雙向通信,無需依賴于客戶端發起請求。服務器可以主動向客戶端推送消息或數據,而不需要等待客戶端發送請求。
-
實時性:WebSocket 提供了低延遲的實時通信能力,適用于需要及時推送數據的場景,如即時聊天、實時消息更新等。
-
長連接:與傳統的 HTTP 請求-響應模式不同,WebSocket 在握手階段建立連接后,連接會保持打開,雙方可以長時間保持通信狀態,避免了頻繁建立和關閉連接的開銷。
-
二進制支持:WebSocket 不僅可以傳輸文本數據,還支持傳輸二進制數據,這使得它能夠處理多媒體數據、文件傳輸等更復雜的場景。
-
適用于 Web 應用和移動應用:WebSocket 可以被廣泛應用于 Web 應用和移動應用中,為實時通信提供了強大的支持。
在使用 WebSocket 進行通信時,開發者可以借助相應的 WebSocket 客戶端庫或者瀏覽器提
供的 WebSocket API 來實現與服務器的連接和數據傳輸。同時,服務器端也需要支持
WebSocket 協議來處理客戶端的連接和消息。
三、總結
關于HTTP請求和WebSocket的對比:
-
連接方式:HTTP 是一種無狀態的請求-響應協議,每次請求都需要重新建立連接。而 WebSocket 則是一種全雙工通信協議,通過一次握手后,客戶端和服務器之間可以保持長時間的連接,實現雙向通信。
-
通信效率:由于 HTTP 協議的特性,每次請求-響應的過程會帶來較大的開銷。而 WebSocket 的長連接可以減少頻繁的握手和頭部信息傳輸,從而提高通信效率,特別適合實時性要求高的場景。
-
數據格式:HTTP 使用文本形式的請求和響應,通常以 JSON 或 XML 格式進行數據傳輸。而 WebSocket 可以傳輸二進制數據,可以更高效地處理多媒體數據或其他復雜的格式。
-
支持性:WebSocket 是一種相對較新的協議,不是所有的瀏覽器和服務器都完全支持它。而 HTTP 是通用的協議,幾乎所有的瀏覽器和服務器都能良好支持。
綜上所述,WebSocket 相對于 HTTP 具有更低的通信延遲、更高的效率和更強大的功能,特別適用于實時通信、推送和實時更新的場景。但在一些簡單的請求-響應交互中,仍然可以使用 HTTP。選擇使用哪種協議取決于具體的需求和場景。
結語
每個人都有自己獨特的才華和潛能,在這個廣袤的世界上,你的存在是有意義的。無論你是誰,你的背景如何,你所處的環境怎樣,只要你敢于跨出舒適區,付出努力,追求卓越,你就能夠開創屬于自己的輝煌。
我們下期見。
每一次努力都是一次進步,即使進展緩慢,也要堅持不懈。
往期文章推薦:
- 關于redis的讀寫一致問題
- springsecurity加入第三方授權認證
- Java連接mysql常遇時間問題