diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:43:23 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:43:23 -0500 |
commit | 218934fa2ed1c702a6d3923d2aa2cc6b43c48684 (patch) | |
tree | a9ef8ac1e1b8fe4207b6d64d3841bfb8990b6fd0 /files/zh-tw/websockets/writing_websocket_client_applications | |
parent | 074785cea106179cb3305637055ab0a009ca74f2 (diff) | |
download | translated-content-218934fa2ed1c702a6d3923d2aa2cc6b43c48684.tar.gz translated-content-218934fa2ed1c702a6d3923d2aa2cc6b43c48684.tar.bz2 translated-content-218934fa2ed1c702a6d3923d2aa2cc6b43c48684.zip |
initial commit
Diffstat (limited to 'files/zh-tw/websockets/writing_websocket_client_applications')
-rw-r--r-- | files/zh-tw/websockets/writing_websocket_client_applications/index.html | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/files/zh-tw/websockets/writing_websocket_client_applications/index.html b/files/zh-tw/websockets/writing_websocket_client_applications/index.html new file mode 100644 index 0000000000..8f1299379f --- /dev/null +++ b/files/zh-tw/websockets/writing_websocket_client_applications/index.html @@ -0,0 +1,179 @@ +--- +title: 製作 WebSocket 客戶端應用程式 +slug: WebSockets/Writing_WebSocket_client_applications +tags: + - WebSockets +translation_of: Web/API/WebSockets_API/Writing_WebSocket_client_applications +--- +<p>{{ draft() }}</p> + +<p>WebSocket 是一種讓瀏覽器與伺服器進行一段互動通訊的技術。使用這項技術的 Webapp 可以直接進行即時通訊而不需要不斷對資料更改進行輪詢(polling)。</p> + +<div class="note"><strong>注:</strong>當我們的系統架構可以寄存 WebSocket 範例之後,我們會提供聊天/伺服器系統實例的幾個範例。</div> + +<h2 id="哪裡有_WebSocket">哪裡有 WebSocket</h2> + +<p>若 JavaScript 代碼的範疇是 {{ domxref("Window") }} 物件或是實作 {{ domxref("WorkerUtils") }} 的物件,則可使用 WebSocket API。也就是可以從 Web Workers 使用 WebSocket。</p> + +<div class="note"><strong>注:</strong>WebSockets API(與底層協定)的開發還在進展中,且目前不同瀏覽器(甚至瀏覽器的不同版本)有很多兼容問題。</div> + +<h2 id="建立一個_WebSocket_物件">建立一個 WebSocket 物件</h2> + +<p>你必須建立一個 <a href="/zh_tw/WebSockets/WebSockets_reference/WebSocket" title="zh tw/WebSockets/WebSockets reference/WebSocket"><code>WebSocket</code></a> 物件才能讓瀏覽器/伺服器得以以 WebSocket 協定進行通訊,此物件在被建立之後會自動與伺服器連線。</p> + +<div class="note"><strong>注:</strong>別忘記在 Firefox 6.0 中 <code>WebSocket</code> 物件仍有前輟,所以在這裡須改成 <code>MozWebSocket</code>。</div> + +<p>WebSocket 的建構方法有一個必要參數與一個選擇參數:</p> + +<pre>WebSocket WebSocket( + in DOMString url, + in optional DOMString protocols +); + +WebSocket WebSocket( + in DOMString url, + in optional DOMString[] protocols +); +</pre> + +<dl> + <dt><code>url</code></dt> + <dd>連線用的 URL,WebSocket 伺服器會回應這個 URL。<br> + <br> + 根據網際網路工程任務小組(Internet Engineering Task Force,IETF)定義之規範, URL 的協議類型必須是 <code>ws://</code> (非加密連線)或是 <code>wss://</code> (加密連線)</dd> + <dt><code>protocols</code> {{ optional_inline() }}</dt> + <dd>一個表示協定的字串或者是一個表示協定的字串構成的陣列。這些字串可以用來指定子協定,因此一個伺服器可以實作多個 WebSocket 子協定(舉例來說,你可以讓一個伺服器處理不同種類的互動情形,各情形以 <code>protocol</code> 分別)。若不指定協定字串則預設值為空字串。</dd> +</dl> + +<p>此建構方法可能拋出以下例外:</p> + +<dl> + <dt><code>SECURITY_ERR</code></dt> + <dd>連線使用的埠被阻擋。</dd> +</dl> + +<h3 id="範例">範例</h3> + +<p>此簡單範例建立了一個新的 WebSocket,連到位於 <code><span class="nowiki">http://www.example.com/socketserver</span></code> 的伺服器。指定的子協定是 "my-custom-protocol"。</p> + +<pre>var mySocket = new WebSocket("<span class="plain">ws://www.example.com/socketserver</span>", "my-custom-protocol"); +</pre> + +<p>回傳之後,<code>mySocket</code> 的 <code>readyState</code> 會變成 <code>CONNECTING</code>。當連線已可以傳輸資料時 <code>readyState</code> 會變成 <code>OPEN</code>。</p> + +<p>要建立一個連線但不指定單一個特定協定,可以指定一個協定構成的陣列:</p> + +<pre>var mySocket = new WebSocket("<span class="plain">ws://www.example.com/socketserver</span>", ["protocol1", "protocol2"]); +</pre> + +<p>當連線建立的時候(也就是 <code>readyState</code> 變成而 <code>OPEN</code> 的時候),<code>protocol</code> 屬性會回傳伺服器選擇的協定。</p> + +<h2 id="傳資料給伺服器">傳資料給伺服器</h2> + +<p>連線開啟之後即可開始傳資料給伺服器。呼叫 <code>WebSocket</code> 的 <a href="/zh_tw/WebSockets/WebSockets_reference/WebSocket#send()" title="zh tw/WebSockets/WebSockets reference/WebSocket#send()"><code>send()</code></a> 來發送訊息:</p> + +<pre>mySocket.send("這是伺服器正迫切需要的文字!"); +</pre> + +<p>可以被傳送的內容包括字串、<a href="/en/DOM/Blob" title="en/DOM/Blob"><code>Blob</code></a> 或是 <a href="/zh_tw/JavaScript_typed_arrays/ArrayBuffer" title="zh tw/JavaScript typed arrays/ArrayBuffer"><code>ArrayBuffer</code></a>。</p> + +<div class="note"><strong>注:</strong>Firefox 目前只支援字串傳送。</div> + +<h3 id="用_JSON_傳輸物件">用 JSON 傳輸物件</h3> + +<p>有一個很方便的方法是用 <a href="/en/JSON" title="en/JSON">JSON</a> 傳送複雜的資料給伺服器,舉例來說,聊天程式可以設計一種協定,這個協定傳送以 JSON 封裝的資料封包:</p> + +<pre class="brush: js">// 透過伺服器傳送文字給所有使用者 + +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 = ""; +} +</pre> + +<p>這份代碼先建立一個物件:<code>msg</code>,它包含伺服器處理訊息所需的種種資訊,然後呼叫 <a href="/en/JavaScript/Reference/Global_Objects/JSON/stringify" title="en/JavaScript/Reference/Global Objects/JSON/stringify"><code>JSON.stringify()</code></a> 使該物件轉換成 JSON 格式並呼叫 WebSocket 的 <a href="/zh_tw/WebSockets/WebSockets_reference/WebSocket#send()" title="zh tw/WebSockets/WebSockets reference/WebSocket#send()"><code>send()</code></a> 方法來傳輸資料至伺服器。</p> + +<h2 id="從伺服器接收訊息">從伺服器接收訊息</h2> + +<p>WebSockets 是一個事件驅動 API,當瀏覽器收到訊息時,一個「message」事件被傳入 <code>onmessage</code> 函數。使用以下方法開始傾聽傳入資料:</p> + +<pre class="brush: js">mySocket.onmessage = function(e) { + console.log(e.data); +} +</pre> + +<h3 id="接收並解讀_JSON_物件">接收並解讀 JSON 物件</h3> + +<p>考慮先前在「用 JSON 傳輸物件」談起的聊天應用程式。客戶端可能收到的資料封包有幾種:</p> + +<ul> + <li>登入握手</li> + <li>訊息文字</li> + <li>更新使用者清單</li> +</ul> + +<p>用來解讀傳入訊息的代碼可能像是:</p> + +<pre class="brush: js">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); + } +}; +</pre> + +<p>這裡我們使用 <a href="/en/JavaScript/Reference/Global_Objects/JSON/parse" title="en/JavaScript/Reference/Global Objects/JSON/parse"><code>JSON.parse()</code></a> 使 JSON 物件轉換成原來的物件,檢驗並根據內容採取行動。</p> + +<h2 id="關閉連線">關閉連線</h2> + +<p>當你想結束 WebSocket 連線的時候,呼叫 WebSocket 的 <a href="/zh_tw/WebSockets/WebSockets_reference/WebSocket#close()" title="zh tw/WebSockets/WebSockets reference/WebSocket#close()"><code>close()</code></a> 方法:</p> + +<pre>mySocket.close(); +</pre> + +<h2 id="參考資料">參考資料</h2> + +<p><a href="https://tools.ietf.org/html/draft-abarth-thewebsocketprotocol-01">IETF: The WebSocket protocol draft-abarth-thewebsocketprotocol-01</a></p> + +<p> </p> + +<p>{{ languages ( {"en": "en/WebSockets/Writing_WebSocket_client_applications"} ) }}</p> + +<dl> +</dl> |