一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

有了HTTP為什么還要有websocket協(xié)議?

小林coding ? 來源:小林coding ? 作者:小林coding ? 2022-10-20 14:34 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

平時我們打開網頁,比如購物網站某寶。都是點一下「列表商品」,跳轉一下網頁就到了「商品詳情」。

從 HTTP 協(xié)議的角度來看,就是點一下網頁上的某個按鈕,前端發(fā)一次 HTTP請 求,網站返回一次 HTTP 響應。這種由客戶端主動請求,服務器響應的方式也滿足大部分網頁的功能場景。

但有沒有發(fā)現(xiàn),這種情況下,服務器從來就「不會主動」給客戶端發(fā)一次消息。就像你喜歡的女生從來不會主動找你一樣。

但如果現(xiàn)在,你在刷網頁的時候「右下角」突然彈出一個小廣告,提示你【一個人在家偷偷才能玩哦】。

求知,好學,勤奮,這些刻在你 DNA 里的東西都動起來了。

你點開后發(fā)現(xiàn)。

長相平平無奇的古某提示你"道士 9 條狗,全服橫著走"。

影帝某輝老師跟你說"系兄弟就來砍我"。

來都來了,你就選了個角色進到了游戲界面里。

這時候,上來就是一個小怪,從遠處走來,然后瘋狂拿木棒子抽你。

你全程沒點任何一次鼠標。服務器就自動將怪物的移動數(shù)據和攻擊數(shù)據源源不斷發(fā)給你了。

這….太暖心了。

感動之余,問題就來了,

像這種看起來服務器主動發(fā)消息給客戶端的場景,是怎么做到的?

在真正回答這個問題之前,我們先來聊下一些相關的知識背景。

b00d2f1c-503a-11ed-a3b6-dac502259ad0.png

使用 HTTP 不斷輪詢

其實問題的痛點在于,怎么樣才能在用戶不做任何操作的情況下,網頁能收到消息并發(fā)生變更。

最常見的解決方案是,網頁的前端代碼里不斷定時發(fā) HTTP 請求到服務器,服務器收到請求后給客戶端響應消息。

這其實時一種「」服務器推的形式。

它其實并不是服務器主動發(fā)消息到客戶端,而是客戶端自己不斷偷偷請求服務器,只是用戶無感知而已。

用這種方式的場景也有很多,最常見的就是掃碼登錄。

比如,某信公眾號平臺,登錄頁面二維碼出現(xiàn)之后,前端網頁根本不知道用戶掃沒掃,于是不斷去向后端服務器詢問,看有沒有人掃過這個碼。而且是以大概 1 到 2 秒的間隔去不斷發(fā)出請求,這樣可以保證用戶在掃碼后能在 1 到 2 秒內得到及時的反饋,不至于等太久

b0234c84-503a-11ed-a3b6-dac502259ad0.png使用HTTP定時輪詢

但這樣,會有兩個比較明顯的問題:

  • 當你打開 F12 頁面時,你會發(fā)現(xiàn)滿屏的 HTTP 請求。雖然很小,但這其實也消耗帶寬,同時也會增加下游服務器的負擔。
  • 最壞情況下,用戶在掃碼后,需要等個 1~2 秒,正好才觸發(fā)下一次 HTTP 請求,然后才跳轉頁面,用戶會感到明顯的卡頓。

使用起來的體驗就是,二維碼出現(xiàn)后,手機掃一掃,然后在手機上點個確認,這時候卡頓等個 1~2 秒,頁面才跳轉。

b029a0d4-503a-11ed-a3b6-dac502259ad0.png不斷輪詢查看是否有掃碼

那么問題又來了,有沒有更好的解決方案?

有,而且實現(xiàn)起來成本還非常低。

長輪詢

我們知道,HTTP 請求發(fā)出后,一般會給服務器留一定的時間做響應,比如 3 秒,規(guī)定時間內沒返回,就認為是超時。

如果我們的 HTTP 請求將超時設置的很大,比如 30 秒,在這 30 秒內只要服務器收到了掃碼請求,就立馬返回給客戶端網頁。如果超時,那就立馬發(fā)起下一次請求。

這樣就減少了 HTTP 請求的個數(shù),并且由于大部分情況下,用戶都會在某個 30 秒的區(qū)間內做掃碼操作,所以響應也是及時的。

b03a1cde-503a-11ed-a3b6-dac502259ad0.png長輪詢

比如,某度云網盤就是這么干的。所以你會發(fā)現(xiàn)一掃碼,手機上點個確認,電腦端網頁就秒跳轉,體驗很好。

b04895fc-503a-11ed-a3b6-dac502259ad0.png長輪詢的方式來替代

像這種發(fā)起一個請求,在較長時間內等待服務器響應的機制,就是所謂的長訓輪機制。我們常用的消息隊列 RocketMQ 中,消費者去取數(shù)據時,也用到了這種方式。

b05d164e-503a-11ed-a3b6-dac502259ad0.pngRocketMQ的消費者通過長輪詢獲取數(shù)據

像這種,在用戶不感知的情況下,服務器將數(shù)據推送給瀏覽器的技術,就是所謂的服務器推送技術,它還有個毫不沾邊的英文名,comet 技術,大家聽過就好。

上面提到的兩種解決方案(不斷輪詢和長輪詢),本質上,其實還是客戶端主動去取數(shù)據。

對于像掃碼登錄這樣的簡單場景還能用用。但如果是網頁游戲呢,游戲一般會有大量的數(shù)據需要從服務器主動推送到客戶端。

這就得說下 websocket 了。

websocket是什么

我們知道 TCP 連接的兩端,同一時間里,雙方都可以主動向對方發(fā)送數(shù)據。這就是所謂的全雙工。

而現(xiàn)在使用最廣泛的HTTP/1.1,也是基于TCP協(xié)議的,同一時間里,客戶端和服務器只能有一方主動發(fā)數(shù)據,這就是所謂的半雙工。

也就是說,好好的全雙工 TCP,被 HTTP/1.1 用成了半雙工。

為什么?

這是由于 HTTP 協(xié)議設計之初,考慮的是看看網頁文本的場景,能做到客戶端發(fā)起請求再由服務器響應,就夠了,根本就沒考慮網頁游戲這種,客戶端和服務器之間都要互相主動發(fā)大量數(shù)據的場景。

所以,為了更好的支持這樣的場景,我們需要另外一個基于TCP的新協(xié)議。

于是新的應用層協(xié)議websocket就被設計出來了。

大家別被這個名字給帶偏了。雖然名字帶了個socket,但其實 socket 和 websocket 之間,就跟雷峰和雷峰塔一樣,二者接近毫無關系。

b0ec0f7a-503a-11ed-a3b6-dac502259ad0.pngwebsocket在四層網絡協(xié)議中的位置

怎么建立websocket連接

我們平時刷網頁,一般都是在瀏覽器上刷的,一會刷刷圖文,這時候用的是 HTTP 協(xié)議,一會打開網頁游戲,這時候就得切換成我們新介紹的 websocket 協(xié)議。

為了兼容這些使用場景。瀏覽器在 TCP 三次握手建立連接之后,都統(tǒng)一使用 HTTP 協(xié)議先進行一次通信。

  • 如果此時是普通的 HTTP 請求,那后續(xù)雙方就還是老樣子繼續(xù)用普通 HTTP 協(xié)議進行交互,這點沒啥疑問。
  • 如果這時候是想建立 websocket 連接,就會在 HTTP 請求里帶上一些特殊的header 頭,如下:
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Key: T2a6wZlAwhgQNqruZ2YUyg==

這些 header 頭的意思是,瀏覽器想升級協(xié)議(Connection: Upgrade),并且想升級成 websocket 協(xié)議(Upgrade: websocket)。同時帶上一段隨機生成的 base64 碼(Sec-WebSocket-Key),發(fā)給服務器。

如果服務器正好支持升級成 websocket 協(xié)議。就會走 websocket 握手流程,同時根據客戶端生成的 base64 碼,用某個公開的算法變成另一段字符串,放在 HTTP 響應的 Sec-WebSocket-Accept 頭里,同時帶上101狀態(tài)碼,發(fā)回給瀏覽器。HTTP 的響應如下:

HTTP/1.1101SwitchingProtocols

Sec-WebSocket-Accept:iBJKv/ALIW2DobfoA4dmr3JHBCY=

Upgrade:websocket

Connection:Upgrade

HTTP 狀態(tài)碼=200(正常響應)的情況,大家見得多了。101 確實不常見,它其實是指協(xié)議切換

b0f4e4d8-503a-11ed-a3b6-dac502259ad0.pngbase64轉為新的字符串

之后,瀏覽器也用同樣的公開算法base64碼轉成另一段字符串,如果這段字符串跟服務器傳回來的字符串一致,那驗證通過。

b0fe02ac-503a-11ed-a3b6-dac502259ad0.png對比客戶端和服務端生成的字符串

就這樣經歷了一來一回兩次 HTTP 握手,websocket就建立完成了,后續(xù)雙方就可以使用 webscoket 的數(shù)據格式進行通信了。

b108a360-503a-11ed-a3b6-dac502259ad0.png建立websocket連接.drawio

websocket抓包

我們可以用wireshark抓個包,實際看下數(shù)據包的情況。

b123f5b6-503a-11ed-a3b6-dac502259ad0.png客戶端請求升級為websocket

上面這張圖,注意畫了紅框的第2445行報文,是websocket的第一次握手,意思是發(fā)起了一次帶有特殊Header的HTTP請求。

b19178de-503a-11ed-a3b6-dac502259ad0.png服務器同意升級為websocket協(xié)議

上面這個圖里畫了紅框的4714行報文,就是服務器在得到第一次握手后,響應的第二次握手,可以看到這也是個 HTTP 類型的報文,返回的狀態(tài)碼是 101。同時可以看到返回的報文 header 中也帶有各種websocket相關的信息,比如Sec-WebSocket-Accept。

b30e7a0e-503a-11ed-a3b6-dac502259ad0.png兩次HTTP請求之后正式使用websocket通信

上面這張圖就是全貌了,從截圖上的注釋可以看出,websocket和HTTP一樣都是基于TCP的協(xié)議。經歷了三次TCP握手之后,利用 HTTP 協(xié)議升級為 websocket 協(xié)議。

你在網上可能會看到一種說法:"websocket 是基于HTTP的新協(xié)議",其實這并不對,因為websocket只有在建立連接時才用到了HTTP,升級完成之后就跟HTTP沒有任何關系了。

這就好像你喜歡的女生通過你要到了你大學室友的微信,然后他們自己就聊起來了。你能說這個女生是通過你去跟你室友溝通的嗎?不能。你跟HTTP一樣,都只是個工具人。

這就有點"借殼生蛋"的那意思。

b347d3f8-503a-11ed-a3b6-dac502259ad0.pngHTTP和websocket的關系

websocket的消息格式

上面提到在完成協(xié)議升級之后,兩端就會用webscoket的數(shù)據格式進行通信。

數(shù)據包在websocket中被叫做,我們來看下它的數(shù)據格式長什么樣子。

b35694f6-503a-11ed-a3b6-dac502259ad0.pngwebsocket報文格式

這里面字段很多,但我們只需要關注下面這幾個。

opcode字段:這個是用來標志這是個什么類型的數(shù)據幀。比如。

  • 等于 1 ,是指text類型(string)的數(shù)據包
  • 等于 2 ,是二進制數(shù)據類型([]byte)的數(shù)據包
  • 等于 8 ,是關閉連接的信號

payload字段:存放的是我們真正想要傳輸?shù)臄?shù)據的長度,單位是字節(jié)。比如你要發(fā)送的數(shù)據是字符串"111",那它的長度就是3。

b3729f02-503a-11ed-a3b6-dac502259ad0.pngimg

另外,可以看到,我們存放** payload 長度的字段有好幾個**,我們既可以用最前面的7bit, 也可以用后面的7+16bit 或 7+64bit。

那么問題就來了。

我們知道,在數(shù)據層面,大家都是 01 二進制流。我怎么知道什么情況下應該讀 7 bit,什么情況下應該讀7+16bit呢?

websocket會用最開始的7bit做標志位。不管接下來的數(shù)據有多大,都先讀最先的7個bit,根據它的取值決定還要不要再讀個 16bit 或 64bit。

  • 如果最開始的7bit的值是 0~125,那么它就表示了 payload 全部長度,只讀最開始的7個bit就完事了。
b38d0aa4-503a-11ed-a3b6-dac502259ad0.pngpayload長度在0到125之間
  • 如果是126(0x7E)。那它表示payload的長度范圍在 126~65535 之間,接下來還需要再讀16bit。這16bit會包含payload的真實長度。
b39ec1fe-503a-11ed-a3b6-dac502259ad0.pngpayload長度在126到65535之間
  • 如果是127(0x7F)。那它表示payload的長度范圍>=65536,接下來還需要再讀64bit。這64bit會包含payload的長度。這能放2的64次方byte的數(shù)據,換算一下好多個TB,肯定夠用了。
b3ab2a16-503a-11ed-a3b6-dac502259ad0.pngpayload長度大于等于65536的情況

payload data字段:這里存放的就是真正要傳輸?shù)臄?shù)據,在知道了上面的payload長度后,就可以根據這個值去截取對應的數(shù)據。

大家有沒有發(fā)現(xiàn)一個小細節(jié),websocket的數(shù)據格式也是數(shù)據頭(內含payload長度) + payload data 的形式。

這是因為 TCP 協(xié)議本身就是全雙工,但直接使用純裸TCP去傳輸數(shù)據,會有粘包的"問題"。為了解決這個問題,上層協(xié)議一般會用消息頭+消息體的格式去重新包裝要發(fā)的數(shù)據。

消息頭里一般含有消息體的長度,通過這個長度可以去截取真正的消息體。

HTTP 協(xié)議和大部分 RPC 協(xié)議,以及我們今天介紹的websocket協(xié)議,都是這樣設計的。

b3c3eae2-503a-11ed-a3b6-dac502259ad0.png消息邊界長度標志

websocket的使用場景

websocket完美繼承了 TCP 協(xié)議的全雙工能力,并且還貼心的提供了解決粘包的方案。

它適用于需要服務器和客戶端(瀏覽器)頻繁交互的大部分場景,比如網頁/小程序游戲,網頁聊天室,以及一些類似飛書這樣的網頁協(xié)同辦公軟件。

回到文章開頭的問題,在使用 websocket 協(xié)議的網頁游戲里,怪物移動以及攻擊玩家的行為是服務器邏輯產生的,對玩家產生的傷害等數(shù)據,都需要由服務器主動發(fā)送給客戶端,客戶端獲得數(shù)據后展示對應的效果。

b3d716da-503a-11ed-a3b6-dac502259ad0.pngwebsocket的使用場景

總結

  • TCP 協(xié)議本身是全雙工的,但我們最常用的 HTTP/1.1,雖然是基于 TCP 的協(xié)議,但它是半雙工的,對于大部分需要服務器主動推送數(shù)據到客戶端的場景,都不太友好,因此我們需要使用支持全雙工的 websocket 協(xié)議。
  • 在 HTTP/1.1 里,只要客戶端不問,服務端就不答?;谶@樣的特點,對于登錄頁面這樣的簡單場景,可以使用定時輪詢或者長輪詢的方式實現(xiàn)服務器推送(comet)的效果。
  • 對于客戶端和服務端之間需要頻繁交互的復雜場景,比如網頁游戲,都可以考慮使用 websocket 協(xié)議。
  • websocket 和 socket 幾乎沒有任何關系,只是叫法相似。
  • 正因為各個瀏覽器都支持 HTTP協(xié) 議,所以 websocket 會先利用HTTP協(xié)議加上一些特殊的 header 頭進行握手升級操作,升級成功后就跟 HTTP 沒有任何關系了,之后就用 websocket 的數(shù)據格式進行收發(fā)數(shù)據。

審核編輯 :李倩


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 服務器
    +關注

    關注

    13

    文章

    9784

    瀏覽量

    87860
  • HTTP
    +關注

    關注

    0

    文章

    525

    瀏覽量

    33119
  • 半雙工
    +關注

    關注

    0

    文章

    13

    瀏覽量

    9215

原文標題:有了 HTTP 協(xié)議,為什么還要有 websocket 協(xié)議?

文章出處:【微信號:小林coding,微信公眾號:小林coding】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    HTTP協(xié)議在工業(yè)領域會用到嗎

    HTTP協(xié)議在工業(yè)領域會用到,并且在工業(yè)互聯(lián)網、設備管理、數(shù)據交互等多個方面發(fā)揮著重要作用,以下為你詳細介紹: 工業(yè)互聯(lián)網場景 設備接入與管理 原理:在工業(yè)互聯(lián)網平臺中,各類工業(yè)設備(如傳感器
    的頭像 發(fā)表于 06-03 09:17 ?184次閱讀

    AWTK-WEB 快速入門(6) - JS WebSocket 應用程序

    WebSocket可以實現(xiàn)雙向通信,適合實時通信場景。本文介紹一下使用Javacript語言開發(fā)AWTK-WEB應用程序,并用WebSocket與服務器通訊。用AWTKDesigner新建一個應用程
    的頭像 發(fā)表于 02-26 11:42 ?347次閱讀
    AWTK-WEB 快速入門(6) - JS <b class='flag-5'>WebSocket</b> 應用程序

    HTTP 協(xié)議對于SEO優(yōu)化的影響

    搜索引擎優(yōu)化(SEO)是提高網站在搜索引擎中的可見性和排名的過程。HTTP協(xié)議作為互聯(lián)網通信的基礎,對SEO有著深遠的影響。 1. HTTP狀態(tài)碼 HTTP狀態(tài)碼是服務器響應客戶端請求
    的頭像 發(fā)表于 12-30 09:29 ?593次閱讀

    如何使用 cURL 測試 HTTP 協(xié)議

    cURL是一個強大的命令行工具,用于傳輸數(shù)據,支持多種協(xié)議,包括HTTP、HTTPS、FTP等。使用cURL測試HTTP協(xié)議可以幫助你理解HTTP
    的頭像 發(fā)表于 12-30 09:26 ?1081次閱讀

    HTTP 1.1 和 HTTP 2.0 的區(qū)別

    HTTP(超文本傳輸協(xié)議)是互聯(lián)網上應用最為廣泛的協(xié)議之一,用于在客戶端和服務器之間傳輸數(shù)據。隨著技術的發(fā)展,HTTP協(xié)議也在不斷地更新和優(yōu)
    的頭像 發(fā)表于 12-30 09:25 ?1091次閱讀

    如何使用 HTTP 協(xié)議進行數(shù)據傳輸

    (用戶)發(fā)送請求,服務器根據請求提供響應。 無狀態(tài)協(xié)議HTTP協(xié)議本身是無狀態(tài)的,這意味著服務器不會保存關于客戶端請求的任何信息,除非使用cookies或session。 方法(Methods) :
    的頭像 發(fā)表于 12-30 09:24 ?1541次閱讀

    如何實現(xiàn) HTTP 協(xié)議的安全性

    協(xié)議的安全性,可以采取以下幾種方法: 1. 使用HTTPS HTTPS(安全超文本傳輸協(xié)議)是HTTP的安全版本,它在HTTP的基礎上通過SSL/TLS
    的頭像 發(fā)表于 12-30 09:22 ?917次閱讀

    HTTP 協(xié)議的工作原理

    HTTP協(xié)議的工作原理 1. HTTP協(xié)議概述 HTTP是一個應用層協(xié)議,它定義
    的頭像 發(fā)表于 12-30 09:21 ?990次閱讀

    HTTP 協(xié)議的基本概念

    HTTP(HyperText Transfer Protocol,超文本傳輸協(xié)議)是一種用于分布式、協(xié)作式、超媒體信息系統(tǒng)的網絡協(xié)議。HTTP 是互聯(lián)網上應用最為廣泛的
    的頭像 發(fā)表于 12-29 15:12 ?1455次閱讀

    socket 與 HTTP 協(xié)議的關系

    在計算機網絡中,Socket和HTTP協(xié)議是兩個非常重要的概念,它們在數(shù)據傳輸和網絡通信中扮演著關鍵的角色。 1. Socket的概念 Socket是一種通信機制,它允許兩個程序(一個客戶端和一個
    的頭像 發(fā)表于 11-12 14:12 ?759次閱讀

    socket與WebSocket的區(qū)別與聯(lián)系

    ) : Socket是一種通信端點,它在網絡編程中用于實現(xiàn)不同主機之間的通信。Socket可以是TCP套接字或UDP套接字,分別對應于TCP(傳輸控制協(xié)議)和UDP(用戶數(shù)據報協(xié)議)。 TCP套接字提供可靠的、面向連接的通信服
    的頭像 發(fā)表于 11-04 09:19 ?1228次閱讀

    socket與HTTP協(xié)議的比較

    (套接字)是一種通信機制,它允許兩個應用程序通過網絡進行雙向通信。在TCP/IP模型中,Socket位于傳輸層和應用層之間,提供一種抽象的接口,使得應用程序可以忽略底層網絡的細節(jié),專注于數(shù)據的發(fā)送和接收。 1.2 HTTP協(xié)議
    的頭像 發(fā)表于 11-01 16:14 ?903次閱讀

    低功耗4G模組HTTP網絡協(xié)議應用

    ?大家好,今天我們來學習合宙Air780E模組LuatOS開發(fā)4G通信中HTTP網絡協(xié)議的應用,實現(xiàn)模組和服務器之間數(shù)據的傳輸。 一、HTTP概述 1.1 簡介 HTTP
    的頭像 發(fā)表于 11-01 07:23 ?595次閱讀
    低功耗4G模組<b class='flag-5'>HTTP</b>網絡<b class='flag-5'>協(xié)議</b>應用

    HTTP協(xié)議下的海外網絡暢游:安全與效率的雙重保障

    在全球化日益加深的今天,HTTP協(xié)議作為互聯(lián)網上最為廣泛使用的通信協(xié)議之一,為海外網絡暢游提供重要的技術支持。在HTTP
    的頭像 發(fā)表于 09-24 08:08 ?409次閱讀

    websocket.c RTOS演示中缺少對wifi_connect()的調用怎么辦?

    在 RTOS SDK 1.3 中,一個名為 /examples/websocket_demo/websocket/websocket.c 的示例。在函數(shù)中有一個名為
    發(fā)表于 07-18 06:37