看完讓你徹底搞懂Websocket原理

来源:https://www.cnblogs.com/wulihong/archive/2018/07/27/9378617.html
-Advertisement-
Play Games

一、websocket與http WebSocket是HTML5出的東西(協議),也就是說HTTP協議沒有變化,或者說沒關係,但HTTP是不支持持久連接的(長連接,迴圈連接的不算) 首先HTTP有 1.1 和 1.0 之說,也就是所謂的 keep-alive ,把多個HTTP請求合併為一個,但是 W ...


一、websocket與http

WebSocket是HTML5出的東西(協議),也就是說HTTP協議沒有變化,或者說沒關係,但HTTP是不支持持久連接的(長連接,迴圈連接的不算)

首先HTTP有 1.1 和 1.0 之說,也就是所謂的 keep-alive ,把多個HTTP請求合併為一個,但是 Websocket 其實是一個新協議,跟HTTP協議基本沒有關係,只是為了相容現有瀏覽器的握手規範而已,也就是說它是HTTP協議上的一種補充可以通過這樣一張圖理解

有交集,但是並不是全部。

另外Html5是指的一系列新的API,或者說新規範,新技術。Http協議本身只有1.0和1.1,而且跟Html本身沒有直接關係。。通俗來說,你可以用HTTP協議傳輸非Html數據,就是這樣=。=

再簡單來說,層級不一樣。

二、Websocket是什麼樣的協議,具體有什麼優點

首先,Websocket是一個持久化的協議,相對於HTTP這種非持久的協議來說。簡單的舉個例子吧,用目前應用比較廣泛的PHP生命周期來解釋。

HTTP的生命周期通過 Request 來界定,也就是一個 Request 一個 Response ,那麼在 HTTP1.0 中,這次HTTP請求就結束了。

在HTTP1.1中進行了改進,使得有一個keep-alive,也就是說,在一個HTTP連接中,可以發送多個Request,接收多個Response。但是請記住 Request = Response, 在HTTP中永遠是這樣,也就是說一個request只能有一個response。而且這個response也是被動的,不能主動發起。

教練,你BB了這麼多,跟Websocket有什麼關係呢?_(:з」∠)_好吧,我正準備說Websocket呢。。

首先Websocket是基於HTTP協議的,或者說借用了HTTP的協議來完成一部分握手。

首先我們來看個典型的 Websocket 握手(借用Wikipedia的。。)

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com

熟悉HTTP的童鞋可能發現了,這段類似HTTP協議的握手請求中,多了幾個東西。我會順便講解下作用。

Upgrade: websocket
Connection: Upgrade

這個就是Websocket的核心了,告訴 Apache 、 Nginx 等伺服器:註意啦,我發起的是Websocket協議,快點幫我找到對應的助理處理~不是那個老土的HTTP。

Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

首先, Sec-WebSocket-Key 是一個 Base64 encode 的值,這個是瀏覽器隨機生成的,告訴伺服器:泥煤,不要忽悠窩,我要驗證尼是不是真的是Websocket助理。

然後, Sec_WebSocket-Protocol 是一個用戶定義的字元串,用來區分同URL下,不同的服務所需要的協議。簡單理解:今晚我要服務A,別搞錯啦~

最後, Sec-WebSocket-Version 是告訴伺服器所使用的 Websocket Draft (協議版本),在最初的時候,Websocket協議還在 Draft 階段,各種奇奇怪怪的協議都有,而且還有很多期奇奇怪怪不同的東西,什麼Firefox和Chrome用的不是一個版本之類的,當初Websocket協議太多可是一個大難題。。不過現在還好,已經定下來啦~大家都使用的一個東西~ 脫水: 服務員,我要的是13歲的噢→_→

然後伺服器會返回下列東西,表示已經接受到請求, 成功建立Websocket啦!

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

這裡開始就是HTTP最後負責的區域了,告訴客戶,我已經成功切換協議啦~

Upgrade: websocket
Connection: Upgrade

依然是固定的,告訴客戶端即將升級的是 Websocket 協議,而不是mozillasocket,lurnarsocket或者shitsocket。

然後, Sec-WebSocket-Accept 這個則是經過伺服器確認,並且加密過後的 Sec-WebSocket-Key 。 伺服器:好啦好啦,知道啦,給你看我的ID CARD來證明行了吧。。

後面的, Sec-WebSocket-Protocol 則是表示最終使用的協議。

至此,HTTP已經完成它所有工作了,接下來就是完全按照Websocket協議進行了。具體的協議就不在這闡述了。

——————技術解析部分完畢——————

你TMD又BBB了這麼久,那到底Websocket有什麼鬼用, http long poll ,或者ajax輪詢 不都可以實現實時信息傳遞麽。

好好好,年輕人,那我們來講一講Websocket有什麼用。來給你吃點胡(蘇)蘿(丹)卜(紅)

三、Websocket的作用

在講Websocket之前,我就順帶著講下 long poll 和 ajax輪詢 的原理。

ajax輪詢

ajax輪詢的原理非常簡單,讓瀏覽器隔個幾秒就發送一次請求,詢問伺服器是否有新信息。

場景再現:

客戶端:啦啦啦,有沒有新信息(Request)

服務端:沒有(Response)

客戶端:啦啦啦,有沒有新信息(Request)

服務端:沒有。。(Response)

客戶端:啦啦啦,有沒有新信息(Request)

服務端:你好煩啊,沒有啊。。(Response)

客戶端:啦啦啦,有沒有新消息(Request)

服務端:好啦好啦,有啦給你。(Response)

客戶端:啦啦啦,有沒有新消息(Request)

服務端:。。。。。沒。。。。沒。。。沒有(Response) —- loop

long poll

long poll 其實原理跟 ajax輪詢 差不多,都是採用輪詢的方式,不過採取的是阻塞模型(一直打電話,沒收到就不掛電話),也就是說,客戶端發起連接後,如果沒消息,就一直不返回Response給客戶端。直到有消息才返回,返回完之後,客戶端再次建立連接,周而複始。

場景再現:

客戶端:啦啦啦,有沒有新信息,沒有的話就等有了才返回給我吧(Request)

服務端:額。。 等待到有消息的時候。。來 給你(Response)

客戶端:啦啦啦,有沒有新信息,沒有的話就等有了才返回給我吧(Request) -loop

從上面可以看出其實這兩種方式,都是在不斷地建立HTTP連接,然後等待服務端處理,可以體現HTTP協議的另外一個特點,被動性。

何為被動性呢,其實就是,服務端不能主動聯繫客戶端,只能有客戶端發起。

簡單地說就是,伺服器是一個很懶的冰箱(這是個梗)(不會、不能主動發起連接),但是上司有命令,如果有客戶來,不管多麼累都要好好接待。

說完這個,我們再來說一說上面的缺陷(原諒我廢話這麼多吧OAQ)

從上面很容易看出來,不管怎麼樣,上面這兩種都是非常消耗資源的。

ajax輪詢 需要伺服器有很快的處理速度和資源。(速度)long poll 需要有很高的併發,也就是說同時接待客戶的能力。(場地大小)

所以 ajax輪詢 和 long poll 都有可能發生這種情況。

客戶端:啦啦啦啦,有新信息麽?

服務端:月線正忙,請稍後再試(503 Server Unavailable)

客戶端:。。。。好吧,啦啦啦,有新信息麽?

服務端:月線正忙,請稍後再試(503 Server Unavailable)

客戶端:然後服務端在一旁忙的要死:冰箱,我要更多的冰箱!更多。。更多。。(我錯了。。這又是梗。。)

言歸正傳,我們來說Websocket吧

通過上面這個例子,我們可以看出,這兩種方式都不是最好的方式,需要很多資源。

一種需要更快的速度,一種需要更多的’電話’。這兩種都會導致’電話’的需求越來越高。

哦對了,忘記說了HTTP還是一個狀態協議。

通俗的說就是,伺服器因為每天要接待太多客戶了,是個健忘鬼,你一掛電話,他就把你的東西全忘光了,把你的東西全丟掉了。你第二次還得再告訴伺服器一遍。

所以在這種情況下出現了,Websocket出現了。他解決了HTTP的這幾個難題。首先,被動性,當伺服器完成協議升級後(HTTP->Websocket),服務端就可以主動推送信息給客戶端啦。所以上面的情景可以做如下修改。

客戶端:啦啦啦,我要建立Websocket協議,需要的服務:chat,Websocket協議版本:17(HTTP Request)

服務端:ok,確認,已升級為Websocket協議(HTTP Protocols Switched)

客戶端:麻煩你有信息的時候推送給我噢。。

服務端:ok,有的時候會告訴你的。

服務端:balabalabalabala

服務端:balabalabalabala

服務端:哈哈哈哈哈啊哈哈哈哈

服務端:笑死我了哈哈哈哈哈哈哈

就變成了這樣,只需要經過一次HTTP請求,就可以做到源源不斷的信息傳送了。(在程式設計中,這種設計叫做回調,即:你有信息了再來通知我,而不是我傻乎乎的每次跑來問你 )

這樣的協議解決了上面同步有延遲,而且還非常消耗資源的這種情況。那麼為什麼他會解決伺服器上消耗資源的問題呢?

其實我們所用的程式是要經過兩層代理的,即HTTP協議在Nginx等伺服器的解析下,然後再傳送給相應的Handler(PHP等)來處理。簡單地說,我們有一個非常快速的 接線員(Nginx) ,他負責把問題轉交給相應的 客服(Handler) 。

本身接線員基本上速度是足夠的,但是每次都卡在客服(Handler)了,老有客服處理速度太慢。,導致客服不夠。Websocket就解決了這樣一個難題,建立後,可以直接跟接線員建立持久連接,有信息的時候客服想辦法通知接線員,然後接線員在統一轉交給客戶。

這樣就可以解決客服處理速度過慢的問題了。

同時,在傳統的方式上,要不斷的建立,關閉HTTP協議,由於HTTP是非狀態性的,每次都要重新傳輸 identity info (鑒別信息),來告訴服務端你是誰。

雖然接線員很快速,但是每次都要聽這麼一堆,效率也會有所下降的,同時還得不斷把這些信息轉交給客服,不但浪費客服的處理時間,而且還會在網路傳輸中消耗過多的流量/時間。

但是Websocket只需要一次HTTP握手,所以說整個通訊過程是建立在一次連接/狀態中,也就避免了HTTP的非狀態性,服務端會一直知道你的信息,直到你關閉請求,這樣就解決了接線員要反覆解析HTTP協議,還要查看identity info的信息。

同時由客戶主動詢問,轉換為伺服器(推送)有信息的時候就發送(當然客戶端還是等主動發送信息過來的。。),沒有信息的時候就交給接線員(Nginx),不需要占用本身速度就慢的客服(Handler)了

——————–

至於怎麼在不支持Websocket的客戶端上使用Websocket。。答案是: 不能

但是可以通過上面說的 long poll 和 ajax 輪詢 來 模擬出類似的效果


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 先介紹一下要解決的問題:react中一個組件A和一個組件B,其中B是被connect(connect是redux中的方法)包裝過的組件,包裝成BContainer,A和BContainer的關係是兄弟關係,在同一個父元素下渲染。現在我們要在點擊A的時候調用B中的方法 解決思路:主要是用到ref獲取B ...
  • hash 要點: 1、不會向後臺發請求;#是用來指導瀏覽器動作的,對伺服器端完全無用。 2、用來跳轉到頁面的指定位置: 為網頁位置指定標識符,有兩個方法。一是使用錨點,比如<a name="print"></a>,二是使用id屬性,比如<div id="print" >。 3、hash改變,會產生一 ...
  • 1,javascript的特點以及和java的區別 javascript是基於對象和事件驅動的語言,應用與客戶端。 javascript是基於對象和事件驅動的語言,應用與客戶端。 js的特點 js的特點 交互性:信息的動態交互 交互性:信息的動態交互 安全性:不能訪問本地磁碟文件 安全性:不能訪問本 ...
  • 相信如果用谷歌瀏覽器做移動端頁面的時候 用touch事件的時候應該遇到過這個東東吧 documet.addEventListener("touchstart",function(){ console.log(123); }); [Violation] Added non-passive event ...
  • 1. 認識網頁 網頁主要由文字、圖像和超鏈接等元素構成。當然,除了這些元素,網頁中還可以包含音頻、視頻以及Flash等。 2. 瀏覽器(顯示代碼) 瀏覽器是網頁顯示、運行的平臺,常用的瀏覽器有IE、火狐(Firefox)、谷歌(Chrome)、Safari和Opera等。我們平時稱為五大瀏覽器。 2 ...
  • vue安裝: vue-cil安裝: 創建webpack實例: tips:(摘自https://blog.csdn.net/Marian96/article/details/73603844) ①、Project name (sanfeng1);項目名稱(sanfeng1)。(確定按enter,否按N ...
  • 1. 語法 有兩種定義正則表達式的方式 字面量形式 引用 MDN 的解釋: pattern :正則表達式的文本。 flags :標誌,可以是具有以下值的任意組合: + g:全局匹配;找到所有匹配,而不是在第一個匹配後停止 + i:忽略大小寫 + m:多行; 將開始和結束字元(^和$)視為在多行上工作 ...
  • 1. 什麼是 ? 前端目前最主流的 打包工具,在它的幫助下,開發者可以輕鬆地實現加密代碼、多平臺相容。而最重要的是,它為 前端工程化 提供了最好支持。 、`react`等大型項目的腳手架都是利用 webpack 搭建。 所以,學習 可以幫助開發者更好的進行基於 語言的開發工作。 2. 怎麼學習 ? ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...