1.簡介
它的最大特點(diǎn)就是泛释,服務(wù)器可以主動向客戶端推送信息,客戶端也可以主動向服務(wù)器發(fā)送信息,是真正的雙向平等對話泻拦,屬于服務(wù)器推送技術(shù)的一種。
其他特點(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ì)介紹了僵蛛。