websocket

定義

1、websocket是html5的的一個(gè)重要組件阿趁;
2膜蛔、WebSocket 是一種基于ws協(xié)議的技術(shù)。使用它可以在客戶端與服務(wù)器之間建立一段連續(xù)的脖阵、全雙工的連接。它彌補(bǔ)了http不適合實(shí)時(shí)通信的重大缺陷墅茉。

image.png

特點(diǎn)

(1)服務(wù)器可以主動(dòng)向客戶端推送信息命黔,客戶端也可以主動(dòng)向服務(wù)器發(fā)送信息呜呐,是真正的雙向平等對(duì)話,屬于服務(wù)器推送技術(shù)的一種悍募。
(2)建立在 TCP 協(xié)議之上蘑辑,服務(wù)器端的實(shí)現(xiàn)比較容易。
(3)與 HTTP 協(xié)議有著良好的兼容性坠宴。默認(rèn)端口也是80和443洋魂,并且握手階段采用 HTTP 協(xié)議,因此握手時(shí)不容易屏蔽喜鼓,能通過(guò)各種 HTTP 代理服務(wù)器副砍。
(4)數(shù)據(jù)格式比較輕量,性能開(kāi)銷小庄岖,通信高效豁翎。
(5)可以發(fā)送文本,也可以發(fā)送二進(jìn)制數(shù)據(jù)隅忿。
(6)沒(méi)有同源限制心剥,客戶端可以與任意服務(wù)器通信。
(7)協(xié)議標(biāo)識(shí)符是ws(如果加密背桐,則為wss)优烧,服務(wù)器網(wǎng)址就是 URL。

協(xié)議的握手過(guò)程

在客戶端和服務(wù)端一開(kāi)始握手的期間链峭,http協(xié)議升級(jí)到WebSocket協(xié)議就建立了連接畦娄,底層都是TCP協(xié)議。一旦建立連接熏版,通過(guò)WebSocket接口可以反復(fù)的發(fā)送消息纷责。

為了建立WebSocket連接,客戶端發(fā)送WebSocket握手請(qǐng)求撼短,服務(wù)器返回一個(gè)WebSocket握手響應(yīng)再膳;

客戶端請(qǐng)求:
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
服務(wù)端響應(yīng):
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

websocket API

創(chuàng)建websocket實(shí)例

首先,我們需要通過(guò)調(diào)用WebSocket構(gòu)造函數(shù)來(lái)創(chuàng)建一個(gè)WebSocket連接曲横,構(gòu)造函數(shù)會(huì)返回一個(gè)WebSocket實(shí)例喂柒,可以用來(lái)監(jiān)聽(tīng)事件。這些事件會(huì)告訴你什么時(shí)候連接建立禾嫉,什么時(shí)候消息到達(dá)灾杰,什么時(shí)候連接關(guān)閉了,以及什么時(shí)候發(fā)生了錯(cuò)誤熙参。WebSocket協(xié)議定義了兩種URL方案艳吠,WS和WSS分別代表了客戶端和服務(wù)端之間未加密和加密的通信。WS(WebSocket)類似于Http URL孽椰,而WSS(WebSocket Security)URL 表示連接是基于安全傳輸層(TLS/SSL)和https的連接是同樣的安全機(jī)制昭娩。

WebSocket的構(gòu)造函數(shù)需要一個(gè)URL參數(shù)和一個(gè)可選的協(xié)議參數(shù)(一個(gè)或者多個(gè)協(xié)議的名字)凛篙,協(xié)議的參數(shù)例如XMPP(Extensible Messaging and Presence Protocol)、SOAP(Simple Object Access Protocol)或者自定義協(xié)議栏渺,服務(wù)端和客服端使用的協(xié)議必須一致呛梆,這樣收發(fā)消息彼此才能理解。而URL參數(shù)需要以WS://或者WSS://開(kāi)頭磕诊,例如:ws://www.websocket.org填物,如果URL有語(yǔ)法錯(cuò)誤,構(gòu)造函數(shù)會(huì)拋出異常霎终。

// WebSocket 對(duì)象作為一個(gè)構(gòu)造函數(shù)滞磺,用于新建 WebSocket 實(shí)例
const ws = new WebSocket('ws://localhost:8282');

websocket事件

WebSocket API是純事件驅(qū)動(dòng),通過(guò)監(jiān)聽(tīng)事件可以處理到來(lái)的數(shù)據(jù)和改變的鏈接狀態(tài)神僵⊙闼ⅲ客戶端不需要為了更新數(shù)據(jù)而輪訓(xùn)服務(wù)器。服務(wù)端發(fā)送數(shù)據(jù)后保礼,消息和事件會(huì)異步到達(dá)沛励。WebSocket編程遵循一個(gè)異步編程模型,只需要對(duì)WebSocket對(duì)象增加回調(diào)函數(shù)就可以監(jiān)聽(tīng)事件炮障。你也可以使用addEventListener()方法來(lái)監(jiān)聽(tīng)目派。

Open

一旦服務(wù)端響應(yīng)WebSocket連接請(qǐng)求,就會(huì)觸發(fā)open事件胁赢。響應(yīng)的回調(diào)函數(shù)稱為onopen企蹭。

ws.onopen=function(){
console.log('connection is opened!');
}
// 指定多個(gè)回調(diào)函數(shù)
ws.addEventListener('open', function (event) {
  console.log(‘connection is open!’)智末;
});

open事件觸發(fā)的時(shí)候谅摄,意味著協(xié)議握手結(jié)束,WebSocket已經(jīng)準(zhǔn)備好收發(fā)數(shù)據(jù)系馆。如果你的應(yīng)用收到open事件送漠,就可以確定服務(wù)端已經(jīng)處理了建立連接的請(qǐng)求,且同意和你的應(yīng)用通信由蘑。

Message

當(dāng)消息被接受會(huì)觸發(fā)消息事件闽寡,響應(yīng)的回調(diào)函數(shù)叫做onmessage。接收的消息類型有文本信息尼酿、二進(jìn)制數(shù)據(jù)(blob和ArrayBuffer兩種類型)爷狈。

ws.onmessage = function(e) {
  const data = e.data;
}
Error

如果發(fā)生意外的失敗會(huì)觸發(fā)error事件,相應(yīng)的函數(shù)稱為onerror,錯(cuò)誤會(huì)導(dǎo)致連接關(guān)閉裳擎。如果你收到一個(gè)錯(cuò)誤事件涎永,那么你很快會(huì)收到一個(gè)關(guān)閉事件,在關(guān)閉事件中也許會(huì)告訴你錯(cuò)誤的原因。

ws.onerror = function(e){
console.log('websocket error', e);
handleErrors(e);
}
Close

當(dāng)連接關(guān)閉的時(shí)候回觸發(fā)這個(gè)事件土辩,對(duì)應(yīng)onclose方法支救,連接關(guān)閉之后抢野,服務(wù)端和客戶端就不能再收發(fā)消息拷淘。

ws.onclose=function(e){
console.log('websocket closed', e);
console.log(e.code);
console.log(e.reason);
console.log(e.wasClean);
}

關(guān)閉事件有三個(gè)屬性可以用來(lái)做異常處理和重獲: wasClean,code和reason。wasClean是一個(gè)bool值指孤,代表連接是否干凈的關(guān)閉启涯。 如果是響應(yīng)服務(wù)端的close事件,這個(gè)值為true恃轩,如果是別的原因结洼,比如因?yàn)槭堑讓覶CP連接關(guān)閉,wasClean為false叉跛。code和reason代表關(guān)閉連接時(shí)服務(wù)端發(fā)送的狀態(tài);

websocket方法

ws.send()

一旦建立了連接松忍,實(shí)例對(duì)象的send()方法可用于向服務(wù)器發(fā)送數(shù)據(jù)。(文本筷厘、blob對(duì)象鸣峭、ArrayBuffer對(duì)象:類型化數(shù)組)

ws.send('message');
ws.close()

使用close方法來(lái)關(guān)閉連接,如果連接已經(jīng)關(guān)閉酥艳,這方法將什么也不做摊溶。調(diào)用close方法之后,將不能發(fā)送數(shù)據(jù)充石。

websocket屬性

WebSocket對(duì)象有三個(gè)屬性莫换,readyState,bufferedAmount和Protocol骤铃。

readyState 常量

返回實(shí)例對(duì)象的當(dāng)前狀態(tài)拉岁,共有四種

CONNECTING:值為0,表示正在連接惰爬。
OPEN:值為1喊暖,表示連接成功,可以通信了补鼻。
CLOSING:值為2哄啄,表示連接正在關(guān)閉。
CLOSED:值為3风范,表示連接已經(jīng)關(guān)閉咨跌,或者打開(kāi)連接失敗。
bufferedAmount

有時(shí)候需要檢查傳輸數(shù)據(jù)的大小硼婿,尤其是客戶端傳輸大量數(shù)據(jù)的時(shí)候锌半。雖然send()方法會(huì)馬上執(zhí)行,但數(shù)據(jù)并不是馬上傳輸寇漫。瀏覽器會(huì)緩存應(yīng)用流出的數(shù)據(jù)刊殉,你可以使用bufferedAmount屬性檢查已經(jīng)進(jìn)入隊(duì)列但還未被傳輸?shù)臄?shù)據(jù)大小殉摔。

protocol

在構(gòu)造函數(shù)中,protocol參數(shù)讓服務(wù)端知道客戶端使用的WebSocket協(xié)議记焊。而WebSocket對(duì)象的這個(gè)屬性就是指的最終服務(wù)端確定下來(lái)的協(xié)議名稱逸月,當(dāng)服務(wù)端沒(méi)有選擇客戶端提供的協(xié)議或者在連接握手結(jié)束之前,這個(gè)屬性都是空的遍膜。

ws.onopen=function(){
console.log(ws.protocol);
}

五碗硬、超級(jí)簡(jiǎn)單的demo

模擬聊天室
模擬股票
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市瓢颅,隨后出現(xiàn)的幾起案子恩尾,更是在濱河造成了極大的恐慌,老刑警劉巖挽懦,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件翰意,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡信柿,警方通過(guò)查閱死者的電腦和手機(jī)冀偶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)角塑,“玉大人蔫磨,你說(shuō)我怎么就攤上這事∑粤妫” “怎么了堤如?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)窒朋。 經(jīng)常有香客問(wèn)我搀罢,道長(zhǎng),這世上最難降的妖魔是什么侥猩? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任榔至,我火速辦了婚禮,結(jié)果婚禮上欺劳,老公的妹妹穿的比我還像新娘唧取。我一直安慰自己,他們只是感情好划提,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布枫弟。 她就那樣靜靜地躺著,像睡著了一般鹏往。 火紅的嫁衣襯著肌膚如雪淡诗。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,365評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音韩容,去河邊找鬼款违。 笑死,一個(gè)胖子當(dāng)著我的面吹牛群凶,可吹牛的內(nèi)容都是我干的插爹。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼座掘,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼递惋!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起溢陪,我...
    開(kāi)封第一講書(shū)人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎睛廊,沒(méi)想到半個(gè)月后形真,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡超全,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年咆霜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嘶朱。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蛾坯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出疏遏,到底是詐尸還是另有隱情脉课,我是刑警寧澤,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布财异,位于F島的核電站倘零,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏戳寸。R本人自食惡果不足惜呈驶,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望疫鹊。 院中可真熱鬧袖瞻,春花似錦、人聲如沸拆吆。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)锈拨。三九已至砌庄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背娄昆。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工佩微, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人萌焰。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓哺眯,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親扒俯。 傳聞我的和親對(duì)象是個(gè)殘疾皇子奶卓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

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

  • WebSocket簡(jiǎn)介 談到Web實(shí)時(shí)推送,就不得不說(shuō)WebSocket撼玄。在WebSocket出現(xiàn)之前夺姑,很多網(wǎng)站為...
    吧啦啦小湯圓閱讀 8,145評(píng)論 15 75
  • 今天在書(shū)店見(jiàn)《俄藏敦煌契約文書(shū)研究》(http://book.douban.com/subject/3591413...
    damyata閱讀 5,773評(píng)論 0 4
  • 我不知道是不是所有人都有一個(gè)想忘記盏浙,卻不能忘記的人,是不是不好的結(jié)局都是因?yàn)闆](méi)有好的開(kāi)始荔茬?在這個(gè)crtl+c加 c...
    朱大靜閱讀 182評(píng)論 0 1
  • 丁酉年正月初四(2017.01.31) 廣東省潮州市湘橋區(qū) 華為P9攝
    阿土阿土阿土閱讀 254評(píng)論 0 4
  • 程默第一次看到夏子妍是在公司門(mén)口废膘,早上上班的時(shí)候。由于來(lái)的較早慕蔚,公司沒(méi)有開(kāi)門(mén)丐黄。然后程默發(fā)現(xiàn)有個(gè)陌生的女孩子在他所在...
    船長(zhǎng)不用帆閱讀 1,234評(píng)論 10 5