您的搜尋結果

    製作 WebSocket 客戶端應用程式

    編撰中
    本頁仍未完成

    WebSocket 是一種讓瀏覽器與伺服器進行一段互動通訊的技術。使用這項技術的 Webapp 可以直接進行即時通訊而不需要不斷對資料更改進行輪詢(polling)。

    注:當我們的系統架構可以寄存 WebSocket 範例之後,我們會提供聊天/伺服器系統實例的幾個代碼片段。

    哪裡有 WebSocket

    若 JavaScript 代碼的範疇是 Window 物件或是實作 WorkerUtils 的物件,則可是用 WebSocket API。也就是可以從 Web Workers 使用 WebSocket。

    注:WebSockets API(與底層協定)的開發還在進展中,且目前不同瀏覽器(甚至瀏覽器的不同版本)有很多兼容問題。

    建立一個 WebSocket 物件

    你必須建立一個 WebSocket 物件才能讓瀏覽器/伺服器得以以 WebSocket 協定進行通訊,此物件在被建立之後會自動與伺服器連線。

    注:別忘記在 Firefox 6.0 中 WebSocket 物件仍有前輟,所以在這裡須改成 MozWebSocket

    WebSocket 的建構方法有一個必要參數與一個選擇參數:

    WebSocket WebSocket(
      in DOMString url,
      in optional DOMString protocols
    );
    
    WebSocket WebSocket(
      in DOMString url,
      in optional DOMString[] protocols
    );
    
    url
    連線用的 URL,WebSocket 伺服器會回應這個 URL。
    protocols 選擇性
    一個表示協定的字串或者是一個表示協定的字串構成的陣列。這些字串可以用來指定子協定,因此一個伺服器可以實作多個 WebSocket 子協定(舉例來說,你可以讓一個伺服器處理不同種類的互動情形,各情形以 protocol 分別)。若不指定協定字串則預設值為空字串。

    此建構方法可能拋出以下例外:

    SECURITY_ERR
    連線使用的埠被阻擋。

    範例

    此簡單範例建立了一個新的 WebSocket,連到位於 http://www.example.com/socketserver 的伺服器。指定的子協定是 "my-custom-protocol"。

    var mySocket = new WebSocket("http://www.example.com/socketserver", "my-custom-protocol");
    

    回傳之後,mySocketreadyState 會變成 CONNECTING。當連線已可以傳輸資料時 readyState 會變成 OPEN

    要建立一個連線但不指定單一個特定協定,可以指定一個協定構成的陣列:

    var mySocket = new WebSocket("http://www.example.com/socketserver", ["protocol1", "protocol2"]);
    

    當連線建立的時候(也就是 readyState 變成而 OPEN 的時候),protocol 屬性會回傳伺服器選擇的協定。

    傳資料給伺服器

    連線開啟之後即可開始傳資料給伺服器。呼叫 WebSocketsend() 來發送訊息:

    mySocket.send("這是伺服器正迫切需要的文字!"); 
    

    可以被傳送的內容包括字串、Blob 或是 ArrayBuffer

    注:Firefox 目前只支援字串傳送。

    用 JSON 傳輸物件

    有一個很方便的方法是用 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 物件

    考慮先前在「用 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();
    

    Document Tags and Contributors

    標籤:
    Contributors to this page: ziyunfei, Kennyluck
    最近更新: ziyunfei,