這一章介紹如何用WebSocket API來控制協議和創建應用,運用http://websocket.org 提供的現有WebSocket服務器,我們可以收發消息、創建一些簡單的WebSocket應用。一步一步的學習使用WebSocket API,最后我們會討論瀏覽器的支持度和連通性。這一章的重點是WebSocket 協議在Web客戶端的應用,在稍后的章節會介紹WebSocket協議以及其使用環境。
綜述:
入門:
// Create new WebSocket connection
var ws = new WebSocket("ws://www.websocket.org");
//測試了下鏈接不上。

// Connecting to the server with one protocol called myProtocol
var ws = new WebSocket("ws://echo.websocket.org", "myProtocol");
//myProtocol 是假設的一個定義好的且符合標准的協議。
你可以傳遞一個協議的數組。
var echoSocket = new WebSocket("ws://echo.websocket.org", ["com.kaazing.echo","example.imaginary.protocol"])
//服務端會選擇其中一個使用
echoSocket.onopen = function(e) {
// Check the protocol chosen by the server
console.log(echoSocket.protocol);
}
輸出:com.kaazing.echo
WebSocket事件:
open:
// Event handler for the WebSocket connection opening
ws.onopen = function(e) {
console.log("Connection open...");
};
open事件觸發的時候,意味着協議握手結束,WebSocket已經准備好收發數據。如果你的應用收到open事件,就可以確定服務端已經處理了建立連接的請求,且同意和你的應用通信。
Message:
// 接受文本消息的事件處理實例:
ws.onmessage = function(e) {
if(typeof e.data === "string"){
console.log("String message received", e, e.data);
} else {
console.log("Other message received", e, e.data);
}
};
除了文本消息,WebSocket消息機制還能處理二進制數據,有Blob和ArrayBuffer兩種類型,在讀取到數據之前需要決定好數據的類型。
// 設置二進制數據類型為blob(默認類型)
ws.binaryType = "blob";
// Event handler for receiving Blob messages
ws.onmessage = function(e) {
if(e.data instanceof Blob){
console.log("Blob message received", e.data);
var blob = new Blob(e.data);
}
};
//ArrayBuffer
ws.binaryType = "arraybuffer";
ws.onmessage = function(e) {
if(e.data instanceof ArrayBuffer){
console.log("ArrayBuffer Message Received", + e.data);
// e.data即ArrayBuffer類型
var a = new Uint8Array(e.data);
}
};
Error
//異常處理
ws.onerror = function(e) {
console.log("WebSocket Error: " , e);
//Custom function for handling errors
handleErrors(e);
};
Close
當然你可以調用close方法斷開與服務端的鏈接來觸發onclose事件,
ws.onclose = function(e) {
console.log("Connection closed", e);
};
連接失敗和成功的關閉握手都會觸發關閉事件,WebSocket的對象的readyState屬性就代表連接的狀態(2代表正在關閉,3代表已經關閉)。關閉事件有三個屬性可以用來做異常處理和重獲: wasClean,code和reason。wasClean是一個bool值,代表連接是否干凈的關閉。 如果是響應服務端的close事件,這個值為true,如果是別的原因,比如因為是底層TCP連接關閉,wasClean為false。code和reason代表關閉連接時服務端發送的狀態,這兩個屬性和給入close方法的code和reason參數是對應的,稍后會描述細節。
WebSocket 方法:
WebSocket 對象有兩個方法:send()和close()
send():
一旦在服務端和客戶端建立了全雙工的雙向連接,可以使用send方法去發送消息,
//發送一個文本消息
ws.send("Hello WebSocket!");
當連接是open的時候send()方法傳送數據,當連接關閉或獲取不到的時候回拋出異常。一個通常的錯誤是人們喜歡在連接open之前發送消息。如下所示:
// 這將不會工作
var ws = new WebSocket("ws://echo.websocket.org")
ws.send("Initial data");
正確的姿勢如下,應該等待open事件觸發后再發送消息。
var ws = new WebSocket("ws://echo.websocket.org")
ws.onopen = function(e) {
ws.send("Initial data");
}
如果想通過響應別的事件去發送消息,可以檢查readyState屬性的值為open的時候來實現。
function myEventHandler(data) {
if (ws.readyState === WebSocket.OPEN) {
//open的時候即可發送
ws.send(data);
} else {
// Do something else in this case.
//Possibly ignore the data or enqueue it.
}
}
發送二進制數據:
// Send a Blob
var blob = new Blob("blob contents");
ws.send(blob);
// Send an ArrayBuffer
var a = new Uint8Array([8,6,7,5,3,0,9]);
ws.send(a.buffer);
Blob對象和JavaScript File API一起使用的時候相當有用,可以發送或接受文件,大部分的多媒體文件,圖像,視頻和音頻文件。這一章末尾會結合File API提供讀取文件內容來發送WebSocket消息的實例代碼。
close()
使用close方法來關閉連接,如果連接以及關閉,這方法將什么也不做。調用close方法只后,將不能發送數據。
ws.close();
close方法可以傳入兩個可選的參數,code(numerical)和reason(string),以告訴服務端為什么終止連接。第三章講到關閉握手的時候再詳細討論這兩個參數。
// 成功結束會話 ws.close(1000, "Closing normally"); //1000是狀態碼,代表正常結束。
WebSocket 屬性
WebSocket對象有三個屬性,readyState,bufferedAmount和Protocol。
readyState:
WebSocket對象通過只讀屬性readyState來傳達連接狀態,它會更加連接狀態自動改變。下表展示了readyState屬性的四個不同的值。
| 屬性 | 值 | 狀態 |
| WebSocket.CONNECTING | 0 | 連接正在進行,但還沒有建立 |
| WebSocket.OPEN | 1 | 連接已經建立,可以發送消息。 |
| WebSocket.CLOSING | 2 | 連接正在進行關閉握手 |
| WebSocket.CLOSED | 3 | 連接已經關閉或不能打開 |
了解當前連接的狀態有助於我們調試。
bufferedAmount:
// 10k
var THRESHOLD = 10240;
//建立連接
var ws = new WebSocket("ws://echo.websocket.org");
// Listen for the opening event
ws.onopen = function () {
setInterval( function() {
//緩存未滿的時候發送
if (ws.bufferedAmount < THRESHOLD) {
ws.send(getApplicationState());
}
}, 1000);
};
//使用bufferedAmount屬性發送數據可以避免網絡飽和。
protocol:
在構造函數中,protocol參數讓服務端知道客戶端使用的WebSocket協議。而WebSocket對象的這個屬性就是指的最終服務端確定下來的協議名稱,當服務端沒有選擇客戶端提供的協議或者在連接握手結束之前,這個屬性都是空的。
完整實例
<h2>Websocket Echo Client</h2>
<div id="output"></div>
// 初始化連接和事件
function setup() {
output = document.getElementById("output");
ws = new WebSocket("ws://echo.websocket.org/echo");
// 監聽open
ws.onopen = function (e) {
log("Connected");
sendMessage("Hello WebSocket!");
}
// 監聽close
ws.onclose = function (e) {
log("Disconnected: " + e.reason);
}
//監聽errors
ws.onerror = function (e) {
log("Error ");
}
// 監聽 messages
ws.onmessage = function (e) {
log("Message received: " + e.data);
//收到消息后關閉
ws.close();
}
}
// 發送消息
function sendMessage(msg) {
ws.send(msg);
log("Message sent");
}
// logging
function log(s) {
var p = document.createElement("p");
p.style.wordWrap = "break-word";
p.textContent = s;
output.appendChild(p);
// Also log information on the javascript console
console.log(s);
}
// Start
setup();

判斷瀏覽器是否支持:
if (window.WebSocket){
console.log("This browser supports WebSocket!");
} else {
console.log("This browser does not support WebSocket.");
}
轉:http://www.cnblogs.com/stoneniqiu/p/5373993.html
