從零開始學(xué)SpringBoot之SpringBoot WebSocket原理篇

前言:

?????這節(jié)我們介紹下WebSocket的原理。

一霜威、websocket與http

WebSocket是HTML5出的協(xié)議泣栈,也就是說HTTP協(xié)議沒有變化,或者說沒關(guān)系抑进,但HTTP是不支持持久連接的(長連接强经,循環(huán)連接的不算)

首先HTTP有 1.1 和 1.0 之說,也就是所謂的 keep-alive 寺渗,把多個HTTP請求合并為一個匿情,但是 Websocket 其實是一個新協(xié)議,跟HTTP協(xié)議基本沒有關(guān)系信殊,只是為了兼容現(xiàn)有瀏覽器的握手規(guī)范而已炬称,也就是說它是HTTP協(xié)議上的一種補充,可以通過這樣一張圖理解:

有交集涡拘,但是并不是全部玲躯。

另外Html5指的是一系列新的API,或者說新規(guī)范鳄乏,新技術(shù)跷车。Http協(xié)議本身只有1.0和1.1,而且跟Html本身沒有直接關(guān)系橱野。通俗來說朽缴,你可以用HTTP協(xié)議傳輸非Html數(shù)據(jù)。

二水援、Websocket是什么樣的協(xié)議密强,具體有什么優(yōu)點

首先,Websocket是一個持久化的協(xié)議蜗元,相對于HTTP這種非持久的協(xié)議來說或渤。

HTTP的生命周期通過 Request 來界定,也就是一個 Request 一個 Response 奕扣,那么在 HTTP1.0 中薪鹦,這次HTTP請求就結(jié)束了。

在HTTP1.1中進行了改進成畦,使得有一個keep-alive距芬,也就是說,在一個HTTP連接中循帐,可以發(fā)送多個Request框仔,接收多個Response。但是請記住 Request = Response拄养, 在HTTP中永遠是這樣离斩,也就是說一個request只能有一個response银舱。而且這個response也是被動的,不能主動發(fā)起跛梗。

跟Websocket有什么關(guān)系呢寻馏?

首先Websocket是基于HTTP協(xié)議的,或者說借用了HTTP的協(xié)議來完成一部分握手核偿。

首先我們來看個典型的 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的童鞋可能發(fā)現(xiàn)了漾岳,這段類似HTTP協(xié)議的握手請求中轰绵,多了幾個東西。我會順便講解下作用尼荆。

2.1 Upgrade和Connection


Upgrade: websocket

Connection: Upgrade


這個就是Websocket的核心了左腔,告訴 Apache 、Tomcat捅儒、 Nginx 等服務(wù)器:注意啦液样,我發(fā)起的是Websocket協(xié)議,快點幫我找到對應(yīng)的助理處理~不是那個老土的HTTP巧还。

2.2 Sec-WebSocket


Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==

Sec-WebSocket-Protocol: chat, superchat

Sec-WebSocket-Version: 13


首先鞭莽,?Sec-WebSocket-Key是一個 Base64 encode 的值,這個是瀏覽器隨機生成的狞悲,告訴服務(wù)器:你妹撮抓,不要忽悠窩妇斤,我要驗證尼是不是真的是Websocket助理摇锋。

然后,?Sec_WebSocket-Protocol是一個用戶定義的字符串站超,用來區(qū)分同URL下荸恕,不同的服務(wù)所需要的協(xié)議。簡單理解:今晚我要服務(wù)A死相,別搞錯啦~

最后融求,?Sec-WebSocket-Version是告訴服務(wù)器所使用的 WebSocket Draft (協(xié)議版本),在最初的時候算撮,Websocket協(xié)議還在 Draft 階段生宛,各種奇奇怪怪的協(xié)議都有,而且還有很多期奇奇怪怪不同的東西肮柜,什么Firefox和Chrome用的不是一個版本之類的陷舅,當(dāng)初Websocket協(xié)議太多可是一個大難題。审洞。不過現(xiàn)在還好莱睁,已經(jīng)定下來啦~大家都使用的一個東西~ 脫水:服務(wù)員,我要的是13歲的噢→_→

然后服務(wù)器會返回下列東西,表示已經(jīng)接受到請求仰剿,成功建立Websocket啦创淡!


HTTP/1.1 101 Switching Protocols

Upgrade: websocket

Connection: Upgrade

Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=

Sec-WebSocket-Protocol: chat



這里開始就是HTTP最后負責(zé)的區(qū)域了,告訴客戶南吮,我已經(jīng)成功切換協(xié)議啦~


Upgrade: websocket

Connection: Upgrade


依然是固定的琳彩,告訴客戶端即將升級的是 Websocket 協(xié)議,而不是mozillasocket部凑,lurnarsocket或者shitsocket汁针。

然后,?Sec-WebSocket-Accept這個則是經(jīng)過服務(wù)器確認砚尽,并且加密過后的 Sec-WebSocket-Key 施无。服務(wù)器:好啦好啦,知道啦必孤,給你看我的ID CARD來證明行了吧猾骡。后面的, Sec-WebSocket-Protocol 則是表示最終使用的協(xié)議敷搪。

至此兴想,HTTP已經(jīng)完成它所有工作了,接下來就是完全按照Websocket協(xié)議進行了赡勘。具體的協(xié)議就不在這闡述了嫂便。

——————技術(shù)解析部分完畢——————

你說了這么久,那到底Websocket有什么鬼用闸与, http long poll 毙替,或者ajax輪詢 不都可以實現(xiàn)實時信息傳遞么。

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

三拷邢、Websocket的作用

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

3.1 ajax輪詢

ajax輪詢的原理非常簡單瞭稼,讓瀏覽器隔個幾秒就發(fā)送一次請求忽洛,詢問服務(wù)器是否有新信息。

場景再現(xiàn):

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

服務(wù)端:沒有(Response)

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

服務(wù)端:沒有。廷臼。(Response)

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

服務(wù)端:你好煩啊绝页,沒有啊。寂恬。(Response)

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

服務(wù)端:好啦好啦,有啦給你初肉。(Response)

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

服務(wù)端:。牙咏。臼隔。。妄壶。沒摔握。。丁寄。氨淌。沒。伊磺。盛正。沒有(Response)?—- loop


3.1?長輪詢(long poll)

long poll?其實原理跟?ajax輪詢?差不多,都是采用輪詢的方式屑埋,不過采取的是阻塞模型(一直打電話豪筝,沒收到就不掛電話),也就是說摘能,客戶端發(fā)起連接后续崖,如果沒消息,就一直不返回Response給客戶端徊哑。直到有消息才返回袜刷,返回完之后聪富,客戶端再次建立連接莺丑,周而復(fù)始。

場景再現(xiàn):

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

服務(wù)端:額。奸披。等待到有消息的時候昏名。。來給你(Response)

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

從上面可以看出其實這兩種方式洪鸭,都是在不斷地建立HTTP連接,然后等待服務(wù)端處理仑扑,可以體現(xiàn)HTTP協(xié)議的另外一個特點览爵,被動性。

何為被動性呢镇饮,其實就是蜓竹,服務(wù)端不能主動聯(lián)系客戶端,只能有客戶端發(fā)起储藐。

簡單地說就是俱济,服務(wù)器是一個很懶的冰箱(這是個梗)(不會、不能主動發(fā)起連接)钙勃,但是上司有命令蛛碌,如果有客戶來,不管多么累都要好好接待辖源。

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

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

ajax輪詢需要服務(wù)器有很快的處理速度和資源。(速度)long poll?需要有很高的并發(fā)彤路,也就是說同時接待客戶的能力秕硝。(場地大小)

所以?ajax輪詢?和?long poll?都有可能發(fā)生這種情況洲尊。

客戶端:啦啦啦啦远豺,有新信息么?

服務(wù)端:月線正忙坞嘀,請稍后再試(503 ServerUnavailable)

客戶端:躯护。。丽涩。棺滞。好吧,啦啦啦矢渊,有新信息么继准?

服務(wù)端:月線正忙,請稍后再試(503 ServerUnavailable)

客戶端:然后服務(wù)端在一旁忙的要死:冰箱矮男,我要更多的冰箱移必!更多。毡鉴。更多崔泵。秒赤。(我錯了。憎瘸。這又是梗倒脓。。)


3.2 WebSocket

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

一種需要更快的速度饲做,一種需要更多的’電話’。這兩種都會導(dǎo)致’電話’的需求越來越高遏弱。

哦對了盆均,忘記說了HTTP還是一個狀態(tài)協(xié)議。

通俗的說就是漱逸,服務(wù)器因為每天要接待太多客戶了泪姨,是個健忘鬼,你一掛電話饰抒,他就把你的東西全忘光了肮砾,把你的東西全丟掉了。你第二次還得再告訴服務(wù)器一遍袋坑。

所以在這種情況下出現(xiàn)了仗处,Websocket出現(xiàn)了。他解決了HTTP的這幾個難題枣宫。首先婆誓,被動性,當(dāng)服務(wù)器完成協(xié)議升級后(HTTP->Websocket)也颤,服務(wù)端就可以主動推送信息給客戶端啦洋幻。所以上面的情景可以做如下修改。

客戶端:啦啦啦翅娶,我要建立Websocket協(xié)議文留,需要的服務(wù):chat,Websocket協(xié)議版本:17(HTTP Request)

服務(wù)端:ok故觅,確認厂庇,已升級為Websocket協(xié)議(HTTPProtocols Switched)

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

服務(wù)端:ok,有的時候會告訴你的替蛉。

服務(wù)端:balabalabalabala

服務(wù)端:balabalabalabala

服務(wù)端:哈哈哈哈哈啊哈哈哈哈

服務(wù)端:笑死我了哈哈哈哈哈哈哈

就變成了這樣贯溅,只需要經(jīng)過一次HTTP請求拄氯,就可以做到源源不斷的信息傳送了。(在程序設(shè)計中它浅,這種設(shè)計叫做回調(diào)译柏,即:你有信息了再來通知我,而不是我傻乎乎的每次跑來問你)

這樣的協(xié)議解決了上面同步有延遲姐霍,而且還非常消耗資源的這種情況鄙麦。那么為什么他會解決服務(wù)器上消耗資源的問題呢?

其實我們所用的程序是要經(jīng)過兩層代理的镊折,即HTTP協(xié)議在Nginx等服務(wù)器的解析下胯府,然后再傳送給相應(yīng)的Handler(PHP等)來處理。簡單地說恨胚,我們有一個非陈钜颍快速的 接線員(Nginx) ,他負責(zé)把問題轉(zhuǎn)交給相應(yīng)的 客服(Handler) 赃泡。

本身接線員基本上速度是足夠的寒波,但是每次都卡在客服(Handler)了,老有客服處理速度太慢升熊。俄烁,導(dǎo)致客服不夠。Websocket就解決了這樣一個難題级野,建立后猴娩,可以直接跟接線員建立持久連接,有信息的時候客服想辦法通知接線員勺阐,然后接線員在統(tǒng)一轉(zhuǎn)交給客戶卷中。這樣就可以解決客服處理速度過慢的問題了。

同時渊抽,在傳統(tǒng)的方式上蟆豫,要不斷的建立,關(guān)閉HTTP協(xié)議懒闷,由于HTTP是非狀態(tài)性的十减,每次都要重新傳輸 identity info (鑒別信息),來告訴服務(wù)端你是誰愤估。

雖然接線員很快速帮辟,但是每次都要聽這么一堆,效率也會有所下降的玩焰,同時還得不斷把這些信息轉(zhuǎn)交給客服由驹,不但浪費客服的處理時間,而且還會在網(wǎng)路傳輸中消耗過多的流量/時間昔园。

但是Websocket只需要一次HTTP握手蔓榄,所以說整個通訊過程是建立在一次連接/狀態(tài)中并炮,也就避免了HTTP的非狀態(tài)性,服務(wù)端會一直知道你的信息甥郑,直到你關(guān)閉請求逃魄,這樣就解決了接線員要反復(fù)解析HTTP協(xié)議,還要查看identity info的信息澜搅。

同時由客戶主動詢問伍俘,轉(zhuǎn)換為服務(wù)器(推送)有信息的時候就發(fā)送(當(dāng)然客戶端還是等主動發(fā)送信息過來的。勉躺。)癌瘾,沒有信息的時候就交給接線員(Nginx),不需要占用本身速度就慢的客服(Handler)了


至于怎么在不支持Websocket的客戶端上使用Websocket赂蕴。柳弄。答案是:不能。但是可以通過上面說的 long poll 和 ajax 輪詢 來 模擬出類似的效果

à參考資料如下概说,文章版權(quán)信息歸原作者所有碧注,轉(zhuǎn)載請注明出處:

看完讓你徹底搞懂Websocket原理

http://www.cnblogs.com/fuqiang88/p/5956363.html

內(nèi)容轉(zhuǎn)自知乎:http://www.zhihu.com/question/20215561

如果覺得文字不過癮,可以通過視頻學(xué)習(xí)SpringBoot糖赔,這里給大家推薦

《從零開始學(xué)SpringBoot》視頻教程鏈接:

https://ke.qq.com/course/1185649?flowToken=1017912


轉(zhuǎn)載自公眾號「SpringBoot」,作者悟纖萍丐。

【?Java全棧技術(shù)分享】,Jacky放典。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末逝变,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子奋构,更是在濱河造成了極大的恐慌壳影,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件弥臼,死亡現(xiàn)場離奇詭異宴咧,居然都是意外死亡,警方通過查閱死者的電腦和手機径缅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門掺栅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人纳猪,你說我怎么就攤上這事氧卧。” “怎么了氏堤?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵沙绝,是天一觀的道長。 經(jīng)常有香客問我,道長宿饱,這世上最難降的妖魔是什么熏瞄? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任脚祟,我火速辦了婚禮谬以,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘由桌。我一直安慰自己为黎,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布行您。 她就那樣靜靜地躺著铭乾,像睡著了一般。 火紅的嫁衣襯著肌膚如雪娃循。 梳的紋絲不亂的頭發(fā)上炕檩,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天,我揣著相機與錄音捌斧,去河邊找鬼笛质。 笑死,一個胖子當(dāng)著我的面吹牛捞蚂,可吹牛的內(nèi)容都是我干的妇押。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼姓迅,長吁一口氣:“原來是場噩夢啊……” “哼敲霍!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起丁存,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤肩杈,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后解寝,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體扩然,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年编丘,在試婚紗的時候發(fā)現(xiàn)自己被綠了与学。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡嘉抓,死狀恐怖索守,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情抑片,我是刑警寧澤卵佛,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響截汪,放射性物質(zhì)發(fā)生泄漏疾牲。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一衙解、第九天 我趴在偏房一處隱蔽的房頂上張望阳柔。 院中可真熱鬧,春花似錦蚓峦、人聲如沸舌剂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽霍转。三九已至,卻和暖如春一汽,著一層夾襖步出監(jiān)牢的瞬間避消,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工召夹, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留岩喷,地道東北人。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓戳鹅,卻偏偏與公主長得像均驶,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子枫虏,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容