圖解WebSocket

csdntup

👏作者簡介:大家好,我是愛寫博客的嗯哼,愛好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常遇時間問題

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/37449.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/37449.shtml
英文地址,請注明出處:http://en.pswp.cn/news/37449.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Qt 加載 libjpeg 庫出現“長跳轉已經運行”錯誤

在我以為升級到 Qt5.15.9 后,運行沒有什么問題時,問題就來了 在加載 jpeg 格式的圖片時,出現了“長跳轉已經運行”的錯誤 這個錯誤一般是由 setjmp/longjmp 函數觸發的,出現的可能的原因有以下幾種(聽聽 chatgpt 的回…

常用的免費敏捷工具

? Scrum中非常強調公開、透明、直接有效的溝通,這也是“可視化的管理工具”在敏捷開發中如此重要的原因之一。通過“可視化的管理工具”讓所有人直觀的看到需求,故事,任務之間的流轉狀態,可以使團隊成員更加快速適應敏捷開發流程…

VMware Workstation 如何啟用復制粘貼

產品:VMware Workstation 16 Pro 版本:16.1.1 build-17801498 我們剛安裝好的 VMware Workstation 會發現無法復制粘貼文件到虛擬機中,如下為解決方案: 1.點擊 虛擬機,點擊 安裝 VMware Tools(T)...。 2.虛擬機下面會…

詳細安裝配置django

安裝配置使用Django。 1,下載安裝 django pip install django 2.創建設置項目 先進入要放置項目的文件夾下 2.1, 創建項目 django-admin startproject Api_project 2.2, 創建app命令 cd Api_project dir看一下是否有 manage.py 文件…

ASPICE流程發布和維護

ASPICE流程發布和維護是指在軟件開發完成后,將軟件發布給客戶,并進行維護和支持。這一過程包括以下步驟: 軟件發布:將符合ASPICE標準的軟件發布給客戶,確保軟件可以正常運行并滿足客戶需求。 用戶培訓:對客…

23牛客多校9 I Non-Puzzle: Segment Pair

也許更好的閱讀體驗 D e s c r i p t i o n \mathcal{Description} Description 給 n n n對區間,要求每對區間恰好選一個使得選出來的 n n n個區間有交集,問有多少方案數 1 ≤ n , l i , r i ≤ 5 1 0 5 1\le n, l_i,r_i\le 510^5 1≤n,li?,ri?≤510…

2023-08-11 LeetCode每日一題(矩陣對角線元素的和)

2023-08-11每日一題 一、題目編號 1572. 矩陣對角線元素的和二、題目鏈接 點擊跳轉到題目位置 三、題目描述 給你一個正方形矩陣 mat,請你返回矩陣對角線元素的和。 請你返回在矩陣主對角線上的元素和副對角線上且不在主對角線上元素的和。 示例 1&#xff1…

企業計算機服務器中了Devos勒索病毒怎么辦,勒索病毒解密

社會在發展,科技在進步,企業的生產也得到了很大改善,但是隨著網絡技術的不斷發展,越來越多的企業遭到的網絡安全威脅開始增多,其中較為明顯的就是勒索病毒攻擊。預防勒索病毒攻擊成為日常生活中不可或缺的一部分工作。…

8,四個類型轉換const_cast、reinterpret_cast、dynamic_cast、static_cast

類型轉換const_cast、reinterpret_cast、dynamic_cast、static_cast const_castreinterpret_castdynamic_caststatic_cast const_cast 被const修飾的函數可以被訪問&#xff0c;但是不能被修改成員變量 const_cast可以去掉const #include <iostream> using namespace s…

SyntaxError: Cannot use import statement outside a module

node環境運行報錯&#xff1a; 解決步驟&#xff1a; 1. npm init -y 2. 在 package.json 文件中加入一條&#xff1a;"type": "module", 3. 保存后再執行即可 附&#xff1a;最好是不要在node用import&#xff0c;否則需要上次配置 建議1&#xff1a;用re…

el-table實現靜態和動態合并單元格 以及內容顯示的問題

實現效果圖 <el-tablev-loading"loading":data"tableData"style"width: 100%":row-class-name"tableRowClassName"size"small"><el-table-column fixed label"序號" width"50"><el-tab…

Detecting Twenty-thousand Classes using Image-level Supervision

Detecting Twenty-thousand Classes using Image-level Supervision 摘要背景方法PreliminariesDetic:具有圖像類別的檢測器loss技術細節擴展Grad-CAMGrad-CAM原理 總結 摘要 摘要 由于檢測數據集的規模較小&#xff0c;目前的物體檢測器在詞匯量方面受到限制。而圖像分類器的數…

LeetCode_03Java_1572. 矩陣對角線元素的和

給你一個正方形矩陣 mat&#xff0c;請你返回矩陣對角線元素的和。 請你返回在矩陣主對角線上的元素和副對角線上且不在主對角線上元素的和。 輸入&#xff1a;mat [[1,2,3],[4,5,6],[7,8,9]] 輸出&#xff1a;25 解釋&#xff1a;對角線的和為&#xff1a;1 5 9 3 7 2…

Scratch 之 3D 介紹及教程

第一章 為什么 3D 很難&#xff1f; 1.1 3D 難在何處&#xff1f; 3D 之所以會使我們覺得困難&#xff0c;是因為 Scratch 軟件只有兩個坐標軸&#xff0c;既&#xff1a;X軸、Y軸。 2維坐標系 而 3D 卻擁有三個坐標軸&#xff1a; 3維坐標系 怎么辦&#xff1f;很簡單&…

Gin各種參數接收

Gin參數接收 文章目錄 Gin參數接收1.各個參數的接收方法Gin中發送JSON數據Gin接收querystring數據Gin接收Form的參數Gin接收URI參數 2.參數綁定方式接收(更加方便)推薦一款軟件 1.各個參數的接收方法 聲明: 這里的c都是c *gin.Context中的c Gin中發送JSON數據 在傳輸或接受JS…

33 | 美國總統數據分析

在這個數據分析項目中,利用Pandas等Python庫對美國2020年7月22日至2020年8月20日期間的超過75萬條捐贈數據進行了深入的探索和分析。通過這一分析,他們揭示了這段時間內美國選民對總統候選人的偏好和捐款情況。以下是對文章中的主要步驟和內容的進一步描述: 數據集處理: 作…

Jquery 復選框點擊生成標簽 源代碼

html <!DOCTYPE html> <html><head><meta charset"utf-8"><title>服務資源管理</title><link rel"stylesheet" type"text/css" href"../lib/layui/css/layui.css" /><link rel"st…

2023牛客第八場補題報告A H J K

2023牛客第八場補題報告A H J K A-Alive Fossils_2023牛客暑期多校訓練營8 (nowcoder.com) 思路 統計字符串&#xff0c;取出現次數為t的。 代碼 #include <bits/stdc.h> #define int long long #define endl \n #define IOS ios::sync_with_stdio(0), cin.tie(0), …

【C++】面試題

1、都說c是面向對象的語言&#xff0c;面向對象的三個特性能 [展開] 介紹一下嗎&#xff1f; 封裝&#xff1a;封裝是一種集中管理的思想&#xff0c;把內部的數據和實現方法組合在一起&#xff0c;并且不對外暴漏內部的數據和實現方法&#xff0c;只對外提供幾個接口來完成函數…

DockePod信號處理機制與僵尸進程優化

Docke&Pod信號處理與僵尸進程優化 容器與信號的關系 SIGTERM信號&#xff1a;程序結束(terminate)信號&#xff0c;這是用來終止進程的標準信號&#xff0c;也是 kill 、 killall 、 pkill 命令所發送的默認信號。與SIGKILL不同的是該信號可以被阻塞和處理。通常用來要求程…