--- title: 製作 WebSocket 客戶端應用程式 slug: Web/API/WebSockets_API/Writing_WebSocket_client_applications tags: - WebSockets translation_of: Web/API/WebSockets_API/Writing_WebSocket_client_applications original_slug: WebSockets/Writing_WebSocket_client_applications ---
{{ draft() }}
WebSocket 是一種讓瀏覽器與伺服器進行一段互動通訊的技術。使用這項技術的 Webapp 可以直接進行即時通訊而不需要不斷對資料更改進行輪詢(polling)。
若 JavaScript 代碼的範疇是 {{ domxref("Window") }} 物件或是實作 {{ domxref("WorkerUtils") }} 的物件,則可使用 WebSocket API。也就是可以從 Web Workers 使用 WebSocket。
你必須建立一個 WebSocket 物件才能讓瀏覽器/伺服器得以以 WebSocket 協定進行通訊,此物件在被建立之後會自動與伺服器連線。
WebSocket 物件仍有前輟,所以在這裡須改成 MozWebSocket。WebSocket 的建構方法有一個必要參數與一個選擇參數:
WebSocket WebSocket( in DOMString url, in optional DOMString protocols ); WebSocket WebSocket( in DOMString url, in optional DOMString[] protocols );
urlws:// (非加密連線)或是 wss:// (加密連線)protocols {{ optional_inline() }}protocol 分別)。若不指定協定字串則預設值為空字串。此建構方法可能拋出以下例外:
SECURITY_ERR此簡單範例建立了一個新的 WebSocket,連到位於 http://www.example.com/socketserver 的伺服器。指定的子協定是 "my-custom-protocol"。
var mySocket = new WebSocket("ws://www.example.com/socketserver", "my-custom-protocol");
回傳之後,mySocket 的 readyState 會變成 CONNECTING。當連線已可以傳輸資料時 readyState 會變成 OPEN。
要建立一個連線但不指定單一個特定協定,可以指定一個協定構成的陣列:
var mySocket = new WebSocket("ws://www.example.com/socketserver", ["protocol1", "protocol2"]);
當連線建立的時候(也就是 readyState 變成而 OPEN 的時候),protocol 屬性會回傳伺服器選擇的協定。
連線開啟之後即可開始傳資料給伺服器。呼叫 WebSocket 的 send() 來發送訊息:
mySocket.send("這是伺服器正迫切需要的文字!");
可以被傳送的內容包括字串、Blob 或是 ArrayBuffer。
有一個很方便的方法是用 JSON 傳送複雜的資料給伺服器,舉例來說,聊天程式可以設計一種協定,這個協定傳送以 JSON 封裝的資料封包:
// 透過伺服器傳送文字給所有使用者
function sendText() {
var msg = {
type: "message",
text: document.getElementById("text").value,
id: clientID,
date: Date.now()
};
mySocket.send(JSON.stringify(msg));
document.getElementById("text").value = "";
}
這份代碼先建立一個物件:msg,它包含伺服器處理訊息所需的種種資訊,然後呼叫 JSON.stringify() 使該物件轉換成 JSON 格式並呼叫 WebSocket 的 send() 方法來傳輸資料至伺服器。
WebSockets 是一個事件驅動 API,當瀏覽器收到訊息時,一個「message」事件被傳入 onmessage 函數。使用以下方法開始傾聽傳入資料:
mySocket.onmessage = function(e) {
console.log(e.data);
}
考慮先前在「用 JSON 傳輸物件」談起的聊天應用程式。客戶端可能收到的資料封包有幾種:
用來解讀傳入訊息的代碼可能像是:
connection.onmessage = function(evt) {
var f = document.getElementById("chatbox").contentDocument;
var text = "";
var msg = JSON.parse(evt.data);
var time = new Date(msg.date);
var timeStr = time.toLocaleTimeString();
switch(msg.type) {
case "id":
clientID = msg.id;
setUsername();
break;
case "username":
text = "<b>使用者 <em>" + msg.name + "</em> 登入於 " + timeStr + "</b><br>";
break;
case "message":
text = "(" + timeStr + ") <b>" + msg.name + "</b>: " + msg.text + "<br>";
break;
case "rejectusername":
text = "<b>由於你選取的名字已被人使用,你的使用者名稱已被設置為 <em>" + msg.name + "</em>。";
break;
case "userlist":
var ul = "";
for (i=0; i < msg.users.length; i++) {
ul += msg.users[i] + "<br>";
}
document.getElementById("userlistbox").innerHTML = ul;
break;
}
if (text.length) {
f.write(text);
document.getElementById("chatbox").contentWindow.scrollByPages(1);
}
};
這裡我們使用 JSON.parse() 使 JSON 物件轉換成原來的物件,檢驗並根據內容採取行動。
當你想結束 WebSocket 連線的時候,呼叫 WebSocket 的 close() 方法:
mySocket.close();
IETF: The WebSocket protocol draft-abarth-thewebsocketprotocol-01
{{ languages ( {"en": "en/WebSockets/Writing_WebSocket_client_applications"} ) }}