javascript 之WebSocket

1.簡介

它的最大特點(diǎn)就是泛释,服務(wù)器可以主動向客戶端推送信息,客戶端也可以主動向服務(wù)器發(fā)送信息,是真正的雙向平等對話泻拦,屬于服務(wù)器推送技術(shù)的一種。

img

其他特點(diǎn)包括:

  • 建立在 TCP 協(xié)議之上忽媒,服務(wù)器端的實(shí)現(xiàn)比較容易争拐。
  • 與 HTTP 協(xié)議有著良好的兼容性。默認(rèn)端口也是80和443猾浦,并且握手階段采用 HTTP 協(xié)議陆错,因此握手時不容易屏蔽,能通過各種 HTTP 代理服務(wù)器金赦。
  • 數(shù)據(jù)格式比較輕量音瓷,性能開銷小,通信高效夹抗。
  • 可以發(fā)送文本绳慎,也可以發(fā)送二進(jìn)制數(shù)據(jù)。
  • 沒有同源限制,客戶端可以與任意服務(wù)器通信杏愤。
  • 協(xié)議標(biāo)識符是ws(如果加密靡砌,則為wss),服務(wù)器網(wǎng)址就是 URL珊楼。

2.客戶端的簡單示例

WebSocket 的用法相當(dāng)簡單通殃。

下面是一個網(wǎng)頁腳本的例子(點(diǎn)擊這里看運(yùn)行結(jié)果),基本上一眼就能明白厕宗。

var ws = new WebSocket("wss://echo.websocket.org");

ws.onopen = function(evt) { 
  console.log("Connection open ..."); 
  ws.send("Hello WebSockets!");
};

ws.onmessage = function(evt) {
  console.log( "Received Message: " + evt.data);
  ws.close();
};

ws.onclose = function(evt) {
  console.log("Connection closed.");
};      

3.客戶端的 API

WebSocket 客戶端的 API 如下画舌。

3.1 WebSocket 構(gòu)造函數(shù)

WebSocket 對象作為一個構(gòu)造函數(shù),用于新建 WebSocket 實(shí)例已慢。

var ws = new WebSocket('ws://localhost:8080');

執(zhí)行上面語句之后曲聂,客戶端就會與服務(wù)器進(jìn)行連接。

實(shí)例對象的所有屬性和方法清單佑惠,參見這里朋腋。

3.2 webSocket.readyState

readyState屬性返回實(shí)例對象的當(dāng)前狀態(tài),共有四種膜楷。

  • CONNECTING:值為0旭咽,表示正在連接。
  • OPEN:值為1赌厅,表示連接成功轻专,可以通信了。
  • CLOSING:值為2察蹲,表示連接正在關(guān)閉请垛。
  • CLOSED:值為3,表示連接已經(jīng)關(guān)閉洽议,或者打開連接失敗宗收。

下面是一個示例。

switch (ws.readyState) {
  case WebSocket.CONNECTING:
    // do something
    break;
  case WebSocket.OPEN:
    // do something
    break;
  case WebSocket.CLOSING:
    // do something
    break;
  case WebSocket.CLOSED:
    // do something
    break;
  default:
    // this never happens
    break;
}

3.3 webSocket.onopen

實(shí)例對象的onopen屬性亚兄,用于指定連接成功后的回調(diào)函數(shù)混稽。

ws.onopen = function () {
  ws.send('Hello Server!');
}

如果要指定多個回調(diào)函數(shù),可以使用addEventListener方法审胚。

ws.addEventListener('open', function (event) {
  ws.send('Hello Server!');
});

3.4 webSocket.onclose

實(shí)例對象的onclose屬性匈勋,用于指定連接關(guān)閉后的回調(diào)函數(shù)。

ws.onclose = function(event) {
  var code = event.code;
  var reason = event.reason;
  var wasClean = event.wasClean;
  // handle close event
};

ws.addEventListener("close", function(event) {
  var code = event.code;
  var reason = event.reason;
  var wasClean = event.wasClean;
  // handle close event
});

3.5 webSocket.onmessage

實(shí)例對象的onmessage屬性膳叨,用于指定收到服務(wù)器數(shù)據(jù)后的回調(diào)函數(shù)洽洁。

ws.onmessage = function(event) {
  var data = event.data;
  // 處理數(shù)據(jù)
};

ws.addEventListener("message", function(event) {
  var data = event.data;
  // 處理數(shù)據(jù)
});

注意,服務(wù)器數(shù)據(jù)可能是文本菲嘴,也可能是二進(jìn)制數(shù)據(jù)(blob對象或Arraybuffer對象)饿自。

ws.onmessage = function(event){
  if(typeof event.data === String) {
    console.log("Received data string");
  }

  if(event.data instanceof ArrayBuffer){
    var buffer = event.data;
    console.log("Received arraybuffer");
  }
}

除了動態(tài)判斷收到的數(shù)據(jù)類型汰翠,也可以使用binaryType屬性,顯式指定收到的二進(jìn)制數(shù)據(jù)類型昭雌。

// 收到的是 blob 數(shù)據(jù)
ws.binaryType = "blob";
ws.onmessage = function(e) {
  console.log(e.data.size);
};

// 收到的是 ArrayBuffer 數(shù)據(jù)
ws.binaryType = "arraybuffer";
ws.onmessage = function(e) {
  console.log(e.data.byteLength);
};

3.6 webSocket.send()

實(shí)例對象的send()方法用于向服務(wù)器發(fā)送數(shù)據(jù)复唤。

發(fā)送文本的例子。

ws.send('your message');

發(fā)送 Blob 對象的例子烛卧。

var file = document
  .querySelector('input[type="file"]')
  .files[0];
ws.send(file);

發(fā)送 ArrayBuffer 對象的例子佛纫。

// Sending canvas ImageData as ArrayBuffer
var img = canvas_context.getImageData(0, 0, 400, 320);
var binary = new Uint8Array(img.data.length);
for (var i = 0; i < img.data.length; i++) {
  binary[i] = img.data[i];
}
ws.send(binary.buffer);

3.7 webSocket.bufferedAmount

實(shí)例對象的bufferedAmount屬性,表示還有多少字節(jié)的二進(jìn)制數(shù)據(jù)沒有發(fā)送出去总放。它可以用來判斷發(fā)送是否結(jié)束雳旅。

var data = new ArrayBuffer(10000000);
socket.send(data);

if (socket.bufferedAmount === 0) {
  // 發(fā)送完畢
} else {
  // 發(fā)送還沒結(jié)束
}

3.8 webSocket.onerror

實(shí)例對象的onerror屬性,用于指定報錯時的回調(diào)函數(shù)间聊。

socket.onerror = function(event) {
  // handle error event
};

socket.addEventListener("error", function(event) {
  // handle error event
});

4.服務(wù)端的實(shí)現(xiàn)

WebSocket 服務(wù)器的實(shí)現(xiàn),可以查看維基百科的列表抵拘。

常用的 Node 實(shí)現(xiàn)有以下三種哎榴。

具體的用法請查看它們的文檔,這里不詳細(xì)介紹了僵蛛。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末尚蝌,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子充尉,更是在濱河造成了極大的恐慌飘言,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件驼侠,死亡現(xiàn)場離奇詭異姿鸿,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)倒源,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門苛预,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人笋熬,你說我怎么就攤上這事热某。” “怎么了胳螟?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵昔馋,是天一觀的道長。 經(jīng)常有香客問我糖耸,道長秘遏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任嘉竟,我火速辦了婚禮垄提,結(jié)果婚禮上榔袋,老公的妹妹穿的比我還像新娘。我一直安慰自己铡俐,他們只是感情好凰兑,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著审丘,像睡著了一般吏够。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上滩报,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天锅知,我揣著相機(jī)與錄音,去河邊找鬼脓钾。 笑死售睹,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的可训。 我是一名探鬼主播昌妹,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼握截!你這毒婦竟也來了飞崖?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤谨胞,失蹤者是張志新(化名)和其女友劉穎固歪,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體胯努,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡牢裳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了叶沛。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贰健。...
    茶點(diǎn)故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖恬汁,靈堂內(nèi)的尸體忽然破棺而出伶椿,到底是詐尸還是另有隱情,我是刑警寧澤氓侧,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布脊另,位于F島的核電站,受9級特大地震影響约巷,放射性物質(zhì)發(fā)生泄漏偎痛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一独郎、第九天 我趴在偏房一處隱蔽的房頂上張望踩麦。 院中可真熱鬧枚赡,春花似錦、人聲如沸谓谦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽反粥。三九已至卢肃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間才顿,已是汗流浹背莫湘。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留郑气,地道東北人幅垮。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像尾组,于是被迫代替她去往敵國和親忙芒。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評論 2 345