WEBSOCKET的原理及業(yè)務(wù)中的使用

有幾點需要首先明確:

1.  websocket是一種協(xié)議憎茂。是html5的一種新協(xié)議;
2.  與http的區(qū)別是惕鼓,它是一種雙向通信協(xié)議,服務(wù)器和客戶端都能主動向?qū)Ψ桨l(fā)送或接受數(shù)據(jù)涯贞;
3.  websocket需要進(jìn)行握手連接之后才能進(jìn)行通信扎谎;

那么我們就知道了websocket誕生的意義了:

傳統(tǒng)的http的請求方式,是客戶端發(fā)送請求服務(wù)端響應(yīng)的形式岭皂,這種方式在應(yīng)對信息變化不是很頻繁的應(yīng)用時還能較好應(yīng)對郊霎,但是對于實時要求高、海量并發(fā)的應(yīng)用來說顯得捉襟見肘爷绘,尤其在當(dāng)前業(yè)界移動互聯(lián)網(wǎng)蓬勃發(fā)展的趨勢下,高并發(fā)與用戶實時響應(yīng)是 Web 應(yīng)用經(jīng)常面臨的問題进倍,比如金融證券的實時信息土至,Web 導(dǎo)航應(yīng)用中的地理位置獲取,社交網(wǎng)絡(luò)的實時消息推送等猾昆。

基于http陶因,我們也有實時通訊的方案,比如輪詢垂蜗,比如使用flash的socket楷扬,但是這些都是非標(biāo)準(zhǔn)的,而且代價較大贴见,html5的標(biāo)準(zhǔn)化組織需要針對實時通訊的應(yīng)用場景提供一套業(yè)界統(tǒng)一的規(guī)范烘苹,那就是websocket。

socket通信方式

socket通信方式

socket的概念最初出現(xiàn)在linux網(wǎng)絡(luò)編程中片部,socket是在應(yīng)用層和傳輸層之間的一個抽象層镣衡,它把TCP/IP層復(fù)雜的操作抽象為幾個簡單的接口供應(yīng)用層調(diào)用已實現(xiàn)進(jìn)程在網(wǎng)絡(luò)中通信。

簡而言之,socket就是對TCP連接建立和釋放的過程進(jìn)行了一層封裝廊鸥,提供出接口給應(yīng)用層是使用望浩。

socket是如何與對應(yīng)網(wǎng)絡(luò)中的進(jìn)程進(jìn)行通信的呢?

我們知道兩個進(jìn)程如果需要進(jìn)行通訊最基本的一個前提能能夠唯一的標(biāo)示一個進(jìn)程惰说,在本地進(jìn)程通訊中我們可以使用PID來唯一標(biāo)示一個進(jìn)程磨德,但PID只在本地唯一,網(wǎng)絡(luò)中的兩個進(jìn)程PID沖突幾率很大吆视,這時候我們需要另辟它徑了剖张,我們知道IP層的ip地址可以唯一標(biāo)示主機,而TCP層協(xié)議和端口號可以唯一標(biāo)示主機的一個進(jìn)程揩环,這樣我們可以利用ip地址+協(xié)議+端口號唯一標(biāo)示網(wǎng)絡(luò)中的一個進(jìn)程搔弄。

那么在進(jìn)行socket接口調(diào)用了時候,傳遞上述唯一標(biāo)識之后丰滑,生成相應(yīng)的協(xié)議請求顾犹,雙向通信就能通過socket進(jìn)行了。

web socket的作用也是模仿socket的通信能力褒墨,但是不同的是炫刷,他本身是一種協(xié)議,瀏覽器和服務(wù)端會對這種協(xié)議進(jìn)行解析郁妈,他是基于基礎(chǔ)TCP連接的浑玛,所以本身它是具有建立雙向連接的能力的,只不過具體的數(shù)據(jù)傳輸方式和一些針對web實時通訊的特性需要在websocket中進(jìn)行定義噩咪。

websocket簡介

傳統(tǒng)的http請求方式:

傳統(tǒng)的http請求方式

websocket的通信方式:

websocket的通信方式

可以看到顾彰,http請求每次客戶端與服務(wù)端交互一定得重新建立連接,但是websocket協(xié)只需要雙方通過握手建立連接胃碾,在連接釋放之前涨享,客戶端和服務(wù)端可以相互接收和傳遞數(shù)據(jù),因為雙方通過協(xié)議是知道建立websocket鏈接各自進(jìn)程的端口的仆百。

在客戶端中厕隧,我們需要使用WebSocket對象,去連接ws://這樣的服務(wù)端url俄周,這樣客戶端就會自動解析并識別websocket請求從而和服務(wù)端通過握手建立連接吁讨。

WebSocket 客戶端連接報文

GET /webfin/websocket/ HTTP/1.1
Host: localhost
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: xqBt3ImNzJbYqRINxEFlkg==
Origin: http://localhost:8080
Sec-WebSocket-Version: 13

其中,“Sec-WebSocket-Key”是 WebSocket 客戶端發(fā)送的一個 base64 編碼的密文峦朗,要求服務(wù)端必須返回一個對應(yīng)加密的“Sec-WebSocket-Accept”應(yīng)答建丧,否則客戶端會拋出“Error during WebSocket handshake”錯誤,并關(guān)閉連接甚垦。

WebSocket 服務(wù)端響應(yīng)報文

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: K7DJLdLooIwIG/MOpvWFB3y3FE8=

“Sec-WebSocket-Accept”的值是服務(wù)端采用與客戶端一致的密鑰計算出來后返回客戶端的,“HTTP/1.1 101 Switching Protocols”表示服務(wù)端接受 WebSocket 協(xié)議的客戶端連接茶鹃,經(jīng)過這樣的請求-響應(yīng)處理后涣雕,客戶端服務(wù)端的 WebSocket 連接握手成功, 后續(xù)就可以進(jìn)行 TCP 通訊了。

具體參考:websocket協(xié)議棧

websocket的實現(xiàn)

要實現(xiàn)websocket闭翩,必須客戶端和服務(wù)端都要支持這個協(xié)議挣郭。

Tomcat在新版本中提供了WebSocketServlet對象,用于支持websocket疗韵。php肯定也有自己的websocket封裝兑障。

而在客戶端html5提供了標(biāo)準(zhǔn)的websocket API,demo實現(xiàn)如下:

var ws = new WebSocket(“ws://echo.websocket.org”);
ws.onopen = function(){ws.send(“Test!”); };
ws.onmessage = function(evt){console.log(evt.data);ws.close();};
ws.onclose = function(evt){console.log(“WebSocketClosed!”);};
ws.onerror = function(evt){console.log(“WebSocketError!”);};
ws.send("hello");//向服務(wù)器發(fā)送消息

第一行代碼是在申請一個 WebSocket 對象蕉汪,參數(shù)是需要連接的服務(wù)器端的地址流译,同 HTTP 協(xié)議開頭一樣,WebSocket 協(xié)議的 URL 使用 ws://開頭者疤,另外安全的 WebSocket 協(xié)議使用 ws://開頭福澡。

第二行到第五行為 WebSocket 對象注冊消息的處理函數(shù),WebSocket 對象一共支持四個消息 onopen, onmessage, onclose 和 onerror驹马,有了這 4 個事件革砸,我們就可以很容易很輕松的駕馭 WebSocket。

當(dāng) Browser 和 WebSocketServer 連接成功后糯累,會觸發(fā) onopen 消息算利;如果連接失敗,發(fā)送泳姐、接收數(shù)據(jù)失敗或者處理數(shù)據(jù)出現(xiàn)錯誤效拭,browser 會觸發(fā) onerror 消息;當(dāng) Browser 接收到 WebSocketServer 發(fā)送過來的數(shù)據(jù)時胖秒,就會觸發(fā) onmessage 消息缎患,參數(shù) evt 中包含 Server 傳輸過來的數(shù)據(jù);當(dāng) Browser 接收到 WebSocketServer 端發(fā)送的關(guān)閉連接請求時扒怖,就會觸發(fā) onclose 消息较锡。我們可以看出所有的操作都是采用異步回調(diào)的方式觸發(fā),這樣不會阻塞 UI盗痒,可以獲得更快的響應(yīng)時間,更好的用戶體驗低散。

業(yè)務(wù)中websocket的使用

在糯米組件的最新迭代中俯邓,支持使用websocket更新shoplist頁面中的訂單狀態(tài)。

在comp/utils/csocket.js中熔号,定義了c端websocket的封裝稽鞭。

調(diào)用new WebSocket建立websocket連接。

websocket不同階段的回調(diào)引镊。

其中message方法用于給某一類服務(wù)端返回的時間注冊回調(diào)朦蕴。

參考文檔:

WebSocket實戰(zhàn)

The WebSocket Protocol

簡單理解Socket

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末篮条,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子吩抓,更是在濱河造成了極大的恐慌涉茧,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,430評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件疹娶,死亡現(xiàn)場離奇詭異伴栓,居然都是意外死亡,警方通過查閱死者的電腦和手機雨饺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評論 3 398
  • 文/潘曉璐 我一進(jìn)店門钳垮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人额港,你說我怎么就攤上這事饺窿。” “怎么了移斩?”我有些...
    開封第一講書人閱讀 167,834評論 0 360
  • 文/不壞的土叔 我叫張陵肚医,是天一觀的道長。 經(jīng)常有香客問我叹哭,道長忍宋,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,543評論 1 296
  • 正文 為了忘掉前任风罩,我火速辦了婚禮糠排,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘超升。我一直安慰自己入宦,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,547評論 6 397
  • 文/花漫 我一把揭開白布室琢。 她就那樣靜靜地躺著乾闰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪盈滴。 梳的紋絲不亂的頭發(fā)上涯肩,一...
    開封第一講書人閱讀 52,196評論 1 308
  • 那天,我揣著相機與錄音巢钓,去河邊找鬼病苗。 笑死,一個胖子當(dāng)著我的面吹牛症汹,可吹牛的內(nèi)容都是我干的硫朦。 我是一名探鬼主播,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼背镇,長吁一口氣:“原來是場噩夢啊……” “哼咬展!你這毒婦竟也來了泽裳?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,671評論 0 276
  • 序言:老撾萬榮一對情侶失蹤破婆,失蹤者是張志新(化名)和其女友劉穎涮总,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體荠割,經(jīng)...
    沈念sama閱讀 46,221評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡妹卿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,303評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了蔑鹦。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片夺克。...
    茶點故事閱讀 40,444評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖嚎朽,靈堂內(nèi)的尸體忽然破棺而出铺纽,到底是詐尸還是另有隱情,我是刑警寧澤哟忍,帶...
    沈念sama閱讀 36,134評論 5 350
  • 正文 年R本政府宣布狡门,位于F島的核電站,受9級特大地震影響锅很,放射性物質(zhì)發(fā)生泄漏其馏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,810評論 3 333
  • 文/蒙蒙 一爆安、第九天 我趴在偏房一處隱蔽的房頂上張望叛复。 院中可真熱鬧,春花似錦扔仓、人聲如沸褐奥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽撬码。三九已至,卻和暖如春版保,著一層夾襖步出監(jiān)牢的瞬間呜笑,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評論 1 272
  • 我被黑心中介騙來泰國打工彻犁, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蹈垢,地道東北人。 一個月前我還...
    沈念sama閱讀 48,837評論 3 376
  • 正文 我出身青樓袖裕,卻偏偏與公主長得像,于是被迫代替她去往敵國和親溉瓶。 傳聞我的和親對象是個殘疾皇子急鳄,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,455評論 2 359

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