webSocket
WebSocket是一個(gè)獨(dú)立的基于TCP的協(xié)議,是HTML5新出的一個(gè)協(xié)議,跟我們認(rèn)識(shí)的HTTP協(xié)議兩者之間具有一定的交集,webSocket其實(shí)是借助了HTTP這個(gè)跳板,B格更上了一個(gè)檔次,能進(jìn)行全雙工通訊(全雙工:允許兩臺(tái)設(shè)備同時(shí)進(jìn)行雙向資料傳輸)。它和HTTP唯一的關(guān)系就是它的握手請(qǐng)求作為一個(gè)升級(jí)請(qǐng)求(Upgrade request),經(jīng)由HTTP服務(wù)器解析。HTTP有1.1和1.0之說(shuō),也就是所謂的keep-alive(Keep-Alive功能使客戶端到服務(wù)器端的連接持續(xù)有效,當(dāng)出現(xiàn)對(duì)服務(wù)器的后繼請(qǐng)求時(shí),Keep-Alive功能避免了建立或者重新建立連接。但是保持鏈接中,暫停通訊期間不會(huì)釋放資源,比較浪費(fèi)服務(wù)器資源。)。但是Websocket其實(shí)是一個(gè)新協(xié)議,跟HTTP協(xié)議基本沒(méi)有關(guān)系,只是為了兼容現(xiàn)有瀏覽器的握手規(guī)范而已,也就是說(shuō)它是HTTP協(xié)議上的一種補(bǔ)充。
協(xié)議
持久化的協(xié)議。HTTP協(xié)議請(qǐng)求:
HTTP 1.0: 一個(gè)request 一個(gè)response 一次HTTP鏈接這樣就算是結(jié)束了。

HTTP 1.1:在1.0版本有了改進(jìn),加入了一個(gè)Keep-Alive,在一次HTTP鏈接中,我可以發(fā)送多個(gè) request,接收多個(gè)response,但是一個(gè)request 只能對(duì)應(yīng) 一個(gè)response。而且這個(gè)response,是被動(dòng)發(fā)起的。

講的什么東東,表示聽(tīng)不懂捏~

本人也是初入江湖,給點(diǎn)時(shí)間消化~
webSocket是基于HTTP協(xié)議,或者說(shuō)是借用了HTTP的協(xié)議來(lái)完成一部分的握手。
GET /chat HTTP/1.1
Host: xxxx.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: XXXXXX
Sec-WebSocket-Protocol: XXXX
Sec-WebSocket-Version: X
Origin:http://xxxx.com
以上就是一次webSocket的握手請(qǐng)求。
有兩個(gè)參數(shù):
Upgrade:webSocket
Connection:Upgrade
告訴服務(wù)器(Ngnix)接線員:attention please!爺發(fā)起的是webSocket協(xié)議,快幫我找一個(gè)對(duì)應(yīng)的客服,不是那個(gè)蹩腳的HTTP客服。
Sec-WebSocket-Key: XXXXX
Sec-WebSocket-Protocol: A, B
Sec-WebSocket-Version: X
首先,Sec-WebSocket-Key 是一個(gè)Base64 encode的值,這個(gè)是瀏覽器隨機(jī)生成的,告訴服務(wù)器:別忽悠我,我要驗(yàn)證你是不是webSocket客服。
然后,Sec_WebSocket-Protocol 是一個(gè)用戶定義的字符串,用來(lái)區(qū)分同URL下,不同的服務(wù)所需要的子協(xié)議(客戶端支持的子協(xié)議列表)。簡(jiǎn)單理解:今晚我要服務(wù)A,別搞錯(cuò)啦~
最后,Sec-WebSocket-Version 是告訴服務(wù)器所使用的Websocket版本 :服務(wù)員,我要的是小學(xué)生,不是大學(xué)生噢→_→然后服務(wù)器會(huì)返回下列東西,表示已經(jīng)接受到請(qǐng)求, 成功建立Websocket啦!
HTTP/1.1101Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: XXXX
Sec-WebSocket-Protocol: B
這部分就是HTTP最后負(fù)責(zé)的內(nèi)容了,此后跟HTTP毫無(wú)關(guān)系。上訴內(nèi)容中:
Upgrade:webSocket
Connection:Upgrade
告訴客戶端,服務(wù)端已經(jīng)成功升級(jí)成了webSocket協(xié)議了。
Sec-WebSocket-Accept: XXXX
這段內(nèi)容是經(jīng)過(guò)服務(wù)確認(rèn)之后,根據(jù)客戶端生成Sec-WebSocket-Key生成的值;簡(jiǎn)單理解,服務(wù)端:來(lái),你個(gè)死傲嬌,給你看我的ID info。
Sec-WebSocket-Protocol表示服務(wù)端從客戶端提供的協(xié)議列表中,提供自身支持哪個(gè)(B)。
接下去的事,表示跟那個(gè)蹩腳的HTTP木有,完全木有,真的木有再有關(guān)系了,webSocket客服完全承包后續(xù)服務(wù)內(nèi)容。
我表示啥都沒(méi)聽(tīng)懂,又給你BBB了這么久,HTTP long pull(長(zhǎng)鏈接) 或者 ajax輪詢,不都可以進(jìn)行實(shí)時(shí)的信息傳遞么?webSocket具體還有什么鬼用處?

年輕人,心急吃不了熱豆腐喲,接下來(lái)我們來(lái)細(xì)細(xì)的說(shuō)說(shuō)WebSocket的作用吧。

作用
在講webSocket之前,請(qǐng)?jiān)试S老夫再BB一會(huì)。讓我們來(lái)腦補(bǔ)一會(huì) long pull 和 ajax輪詢吧
ajax輪詢
ajax的原理非常簡(jiǎn)單,就是定時(shí)器,每隔一會(huì)發(fā)起一個(gè)請(qǐng)求,輪詢服務(wù)端是否有新的信息
場(chǎng)景大致是這樣的:
客戶:我的快遞到了沒(méi)呀?(request)
客服:你好,你是?沒(méi)有(response)
客戶:我的快遞到了沒(méi)呀?
客服:你好,你是?沒(méi)有..
客戶:我的快遞到了沒(méi)呀?
客服:你好,你是?沒(méi)有,真沒(méi)有
客戶:我的快遞到了沒(méi)呀?
客服:你好,你是?!@#$%&*,可能還再路上
客戶:我的快遞到了沒(méi)呀?
客服:你好,你是?有了會(huì)給你送來(lái)的
客戶:我的快遞到了沒(méi)呀?
客服:你好,你是?沒(méi).....沒(méi).....沒(méi)有啊....啊啊啊啊
long pull
原理其實(shí)跟ajax差不多,但是采用的是阻塞的方式(電話接通不掛,直到我滿意為止才掛電話)。
客戶端發(fā)起請(qǐng)求之后,服務(wù)端沒(méi)有消息就一直不返回response。直到有消息,服務(wù)端返回response,客戶端再次建立鏈接,周而復(fù)始。
簡(jiǎn)單理解大致是這樣的:
客戶:有木有新消息呀?有了再回答我(request)
客服:你好,你是?(客戶BB一串),稍等!有消息了,BBBBBB(response)
客戶:有木有新消息呀?有了再回答我(request)
again and again
從上面可以看出其實(shí)這兩種方式,都是在不斷地建立HTTP連接,然后等待服務(wù)端處理,可以體現(xiàn)HTTP協(xié)議的另外一個(gè)特點(diǎn),被動(dòng)性。服務(wù)端不會(huì)主動(dòng)去聯(lián)系客戶端,只能由客戶端主動(dòng)訪問(wèn)。
簡(jiǎn)單地說(shuō)就是,服務(wù)器是就是客服,但是領(lǐng)導(dǎo)有命令,如果有客戶來(lái),不管多么累都要好好接待。還有一個(gè)特性就是,HTTP的非狀態(tài)性,每次都需要詢問(wèn)人員身份。
咱們繼續(xù)再BB一會(huì)吧,這兩種方式其實(shí)都是非常耗資源的。
ajax:需要服務(wù)端有很高效的處理能力
long pull :很考驗(yàn)高并發(fā)的能力;通俗來(lái)說(shuō)同時(shí)接待客戶的能力
正常情況這兩種方式都會(huì)出現(xiàn)一個(gè)現(xiàn)象:
客戶:今晚我需要大保健服務(wù)(request)
客服:對(duì)不起,當(dāng)前座席正忙(HTTP CODE:503)
webSocket
為了解決上訴的問(wèn)題,我們的hero出現(xiàn)了

變被動(dòng)為主動(dòng)
客戶端HTTP協(xié)議升級(jí)成webSocket協(xié)議,服務(wù)端就可以主動(dòng)推送信息給客戶端,而不是每次都是客戶端都傻乎乎的來(lái)詢問(wèn)一次。
客戶:啦啦啦,我要建立Websocket協(xié)議,需要的服務(wù):XXX 協(xié)議版本:x(HTTP Request)
客服:ok,確認(rèn),已升級(jí)為Websocket協(xié)議(HTTP Protocols Switched)
客戶:麻煩你有信息的時(shí)候推送給我噢。。
客服:ok,有的時(shí)候會(huì)告訴你的。
客服:BalaBalaBalaBalaBalaBalaBala
客服:BalaBalaBalaBalaBala
客服:BalaBalaBala
只需要進(jìn)行一次HTTP請(qǐng)求,就可以持續(xù)的從服務(wù)端拿數(shù)據(jù)了。解決了上面兩種的同步,而且還有延遲,非常耗資源的情況
解決服務(wù)器上消耗資源
其實(shí)我們所用的程序是要經(jīng)過(guò)兩層代理的,即HTTP協(xié)議在Nginx服務(wù)器的解析下,然后再傳送給java來(lái)處理。簡(jiǎn)單地說(shuō),我們有一個(gè)非??焖俚慕泳€員(Nginx),他負(fù)責(zé)把問(wèn)題轉(zhuǎn)交給相應(yīng)的客服(java)。本身接線員基本上速度是足夠的,但是每次都卡在客服(java)了,老有客服處理速度太慢,導(dǎo)致客服不夠。
Websocket就解決了這樣一個(gè)難題,建立后,可以直接跟接線員建立持久連接,有信息的時(shí)候客服想辦法通知接線員,然后接線員在統(tǒng)一轉(zhuǎn)交給客戶。這樣就可以解決客服處理速度過(guò)慢的問(wèn)題了。
同時(shí),在傳統(tǒng)的方式上,要不斷的建立,關(guān)閉HTTP協(xié)議,由于HTTP是非狀態(tài)性的,每次都要重新傳輸ID info(鑒別信息),來(lái)告訴服務(wù)端你是誰(shuí)。雖然接線員很快速,但是每次都要聽(tīng)這么一堆,效率也會(huì)有所下降的,同時(shí)還得不斷把這些信息轉(zhuǎn)交給客服,不但浪費(fèi)客服的處理時(shí)間,而且還會(huì)在網(wǎng)路傳輸中消耗過(guò)多的流量/時(shí)間。
但是Websocket只需要一次HTTP握手,所以說(shuō)整個(gè)通訊過(guò)程是建立在一次連接/狀態(tài)中,也就避免了HTTP的非狀態(tài)性,服務(wù)端會(huì)一直知道你的信息,直到你關(guān)閉請(qǐng)求,這樣就解決了接線員要反復(fù)解析HTTP協(xié)議,還要查看ID info的信息。
同時(shí)由客戶主動(dòng)詢問(wèn),轉(zhuǎn)換為服務(wù)器(推送)有信息的時(shí)候就發(fā)送(當(dāng)然客戶端還是等主動(dòng)發(fā)送信息過(guò)來(lái)的。。),沒(méi)有信息的時(shí)候就交給接線員(Nginx),不需要占用本身速度就慢的客服(java)了
保持?jǐn)?shù)據(jù)是最新的
相對(duì)于輪詢來(lái)說(shuō),ajax輪詢是需要通過(guò)客戶端不斷的請(qǐng)求,務(wù)必會(huì)導(dǎo)致請(qǐng)求的時(shí)候服務(wù)端的數(shù)據(jù)還沒(méi)有更新,導(dǎo)致不必要的流量浪費(fèi),無(wú)謂的請(qǐng)求。

最近在做母嬰頻道,希望能夠得到關(guān)注拉啦啦啦
