服務器端推送技術在web開發中比較常用,在早期最簡單的解決方案是采用ajax向服務器輪詢消息,這種方式的輪詢頻率不好控制,會導致服務器的壓力。稍優的方案為:當客戶端向服務器發送請求時,服務器端會抓住這個請求不放,等有數據更新的時候才返回給客戶端,當客戶端接收到數據后再次發送請求,周而復始,這樣就大大減少了請求次數,減輕了服務器的壓力。這里我么使用webSokcet實現服務器端消息推送。
下面我們一次說一下什么是 websocket 已經如何實用js 實現對websocket 數據的獲取,并實現數據交互的長連接。
1. 什么是websocket及特點:
由于http請求只能由客戶端發起,所有當服務器資源有變化時,客戶端只能通過輪詢的方式。非常浪費資源。
websocket的特點:
服務器可以主動向客戶端推送信息,客戶端也可以主動向服務器發送信息,是真正的雙向平等對話,屬于服務器推送技術的一種建立在 TCP 協議之上,服務器端的實現比較容易可以發送文本,也可以發送二進制數據沒有同源限制,客戶端可以與任意服務器通信協議標識符是ws(如果加密,則為wss),服務器網址就是 URL。如ws:localhost:8081/msg.
2. JS示例
var ws = new WebSocket("ws://localhost:8080/msg");
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
1. websocket構造函數
用于創建一個webSocket實例,執行后,客戶端就會與服務端連接
var ws = new WebSocket("ws://localhost:8080/msg");
2. webSocket.readyState
readyState屬性返回實例對象的當前狀態,共有四種。
CONNECTING:值為0,表示正在連接。
OPEN:值為1,表示連接成功,可以通信了。
CLOSING:值為2,表示連接正在關閉。
CLOSED:值為3,表示連接已經關閉,或者打開連接失敗
例如:if(ws.readyState ==WebSocket.CONNECTING){}
3. webSocket.onopen
用于指定連接成功后的回調函數
ws.onopen = function(evt) {
console.log("Connection open ...");
ws.send("Hello WebSockets!");
};
或者:
ws.addEventListener('open', function (event) {
ws.send('Hello Server!');
});
4. webSocket.onclose
用于指定連接關閉后的回調函數。
ws.onclose = function(event) {
var code = event.code;
var reason = event.reason;
var wasClean = event.wasClean;
};
ws.addEventListener("close", function(event) {
var code = event.code;
var reason = event.reason;
var wasClean = event.wasClean;
});
5. webSocket.onmessage
用于指定收到服務器數據后的回調函數
ws.onmessage = function(event) {
var data = event.data;
};
ws.addEventListener("message", function(event) {
var data = event.data;
});
服務器數據有可能是文本,也有可能是二進制數據,需要判斷
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");
}
}
除了動態判斷收到的數據類型,也可以使用binaryType屬性,顯式指定收到的二進制數據類型
// 收到的是 blob 數據
ws.binaryType = "blob";
ws.onmessage = function(e) {
console.log(e.data.size);
};
// 收到的是 ArrayBuffer 數據
ws.binaryType = "arraybuffer";
ws.onmessage = function(e) {
console.log(e.data.byteLength);
};
6. webSocket.send()
send方法用于向服務器發送數據
發送文本
ws.send("Hello WebSockets!");
發送Blob數據
var file = document
.querySelector('input[type="file"]')
.files[0];
ws.send(file);
發送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);
7. webSocket.bufferedAmount
bufferedAmount屬性,表示還有多少字節的二進制數據沒有發送出去。它可以用來判斷發送是否結束
var data = new ArrayBuffer(10000000);
socket.send(data);
if (socket.bufferedAmount === 0) {
// 發送完畢
} else {
// 發送還沒結束
}
8. webSocket.onerror
用于指定報錯時的回調函數
ws.onerror = function(event) {
};
es.addEventListener("error", function(event) {
});
至此,一個基于JS的WebSocket通信實例構建完畢。






