WebSocket 基本介紹及使用筆記

WebSocket 基本介紹及使用筆記
WebSocket 基本介紹及使用筆記

WebSocket 前端得懂一點

最近遇到的一個案子,需要做一個像聊天室的功能,因為有幾位後端之前有研究 SignalR,因此就是他們給了 Augutsut 一段範例碼後,August 就拿來套用而已,沒有說很了解。

後來漸漸被提到這個聊天室想要新增很多功能,大家初步討論了一下,都說需要用到 WebSocket,不然前端就要傻傻的一直 POST 給 Server。

因為之後會實際應用,就決定來看一下 WebSocekt API,並整理成這篇筆記文,之後要用的時候方便查找。


WebSocket 重點心智圖

Google 了一下 MDN 跟菜鳥教程後,把吸收到的 WebSocket 基本應用整理成了一個心智圖,如下:

WebSocket重點心智圖(點擊看原圖)
WebSocket 重點心智圖(點擊看原圖)

以下就是實際來使用一下。


用 Node.js 建一個簡單的 WebSocket Server

因為 WebSocket 的一個特色就是 Server 可以主動發訊息給Client端,因此就必須要建立一個 WebSocket Server 才能夠測試。

Node.js 有一個「WS」的套件,可參考官方說明:ws: a Node.js WebSocket library

安裝 ws

新增一個資料夾,用終端機開啟後輸入:npm init -y,按下 Enter。

接著再輸入:npm install ws,按下 Enter,就安裝完成了。

建立 WS Server 基本程式碼

這段直接 copy 說明文件的,新增一個 index.js 檔案,貼上以下程式碼:

const WebSocket = require('ws');
 
const wss = new WebSocket.Server({
  port: 8080
});

wss.on('connection', function connection(ws) {
  console.log('server connection')
  ws.on('message', function incoming(message) {
    console.log('received: %s', message);
  });
  ws.send('something');
});

因為 August 有裝 Nodemon,因此在終端機輸入:nodemon index.js,按下 Enter,WS Server 就 on 起來了。

成功的話,我們建立出的 WS Server URL 就會是這樣:

ws://localhost:8080/

當 Client 端連上後,就會看見終端機印出訊息,像這樣:

成功連結後印出的訊息
成功連結後印出的訊息

前端連結 WebSocket

建立好了 WebSocket Server,接著就可以開始實做前端連結的部份。

1 建立 WebSocket

建立 WebSocket 的程式碼:

var ws = new WebSocket(url, [protocol]);

url 為必填,就是要填 WS Server URL,像我們上一段最後建立的 ws://localhost:8080/ 這樣。

protocol 為選填,有多個的話可以寫成陣列。MDN 上面針對這個值的解譯是:

一個表示協定的字串或者是一個表示協定的字串構成的陣列。這些字串可以用來指定子協定,因此一個伺服器可以實作多個 WebSocket 子協定(舉例來說,你可以讓一個伺服器處理不同種類的互動情形,各情形以 protocol 分別)。若不指定協定字串則預設值為空字串。

建立完 WebSocket 後,我們可以 console.log(ws) 看一下有什麼:

console.log(ws)
console.log(ws)

readyState,連結 WS Server 的回應碼,總共有 4 碼,代表意思如下:

  • 0 – 表示連接尚未建立。
  • 1 – 表示連接已建立,可以進行通信。
  • 2 – 表示連接正在進行關閉。
  • 3 – 表示連接已經關閉或者連接不能打開。

所以像上面截圖中顯示的是「1」,代表成功連結上了 WS Server。

bufferedAmount,代表 Client 端要傳給 Server 的訊息已被 send() 放入正在隊列中等待傳輸,但是還沒有發出。

onopenonerroroncloseonmessage,這 4 個是連接 WS Server 後會有的事件,介紹於下一段。


2 監聽 WebSocket 事件

當連結上 WS Server 後,Server 就可以主動發訊息給前端,前端這邊不用一直 POST 去查有沒有什麼更新,只要監聽 Server 有沒有發新的訊息來就可以了。

WebSocket 的事件共有 4 個:onopen、onerror、onclose、onmessage。

open

跟 WS Server 連接建立時會觸發:

ws.addEventListener('open', function() {
  console.log('連結建立成功。')
})

error

通信發生錯誤時觸發。

close

關閉跟 WS Server 的連線時觸發:

ws.addEventListener('close', function() {
  console.log('連結關閉,咱們下次見~')
})

message

收到 Server 發來的訊息時觸發,這是最重要的一個事件,WebSocket 優秀的地方就在這,可以監聽由 Server 主動發來的訊息。

ws.addEventListener('message', function(e) {
  var msg = JSON.parse(e.data);
  console.log(msg)
})

這個 function 一整個跟 postMessage 好像,所以看到也不會覺得陌生。

之所以要將傳來的 e.data JSON.parse,原因是 WS Server 傳來的格式會是字串,如果 Server 傳來的格式直接是 JSON 未轉成字串的話,前後端都會報錯。

因為 MDN 特地標了一句「Firefox 目前只支援字串傳送」,所以實際要應用時,建議不論前後端都傳字串就好,畢竟 Firefox 是有一定市佔率的。

August 這邊直接在 Node.js 的部份加入一個 setTimeout 10 秒後傳個訊息出來:

wss.on('connection', function connection(ws) {
  var data = { name: "August", blog: "Let's Write" }
  setTimeout(function() {
    ws.send(JSON.stringify(data));
  }, 10000);
});

之後在瀏覽器上等了 10 秒就有成功看到,代表 WebSocket 真的可以讓 Server 主動發訊息到前端這。

成功看見訊息
成功看見訊息

3 Client 端發訊息給 WS Server

WebSocket 是讓前後端可以互通訊息的,因此除了接收由後端來的訊息,前端也可以主動發訊息給後端。

WebSocket API,methods 有2個:sendclose

send 就是發訊息,close 就是關閉跟 WS Server 的連結。

send

這邊一樣前端 10 秒後發個訊息出去,WS Server 監聽一個 on message 的事件。

前端 發訊息:

setTimeout(function() {
  var testMsg = {name: "August", blog: "Let's Write"};
  ws.send(JSON.stringify(testMsg))
}, 10000)

後端 收訊息:

wss.on('connection', function connection(ws) {
  ws.on('message', function incoming(message) {
    console.log(JSON.parse(message));
  });
});

測試後,終端機成功看到訊息:

後端收到前端訊息
後端收到前端訊息

close

前端如果要主動斷開跟 WS Server 的連結,就是用 close。

這邊一樣寫一個在 10 秒後 close,並且加一個監聽 close 的事件:

ws.addEventListener('close', function(e) {
  console.log(e)
})
setTimeout(function() {
  ws.close()
}, 5000)

最後就會看到印出來的訊息是這樣:

close的console.log(點擊看原圖)
close 的 console.log(點擊看原圖)

筆記後心得

這篇是對 WebSocket API 的筆記整理,實際應用上比較多的情況是用在聊天室,所以後端收到 message 後,要再主動把收到的訊息發給所有有連結的前端,才能讓聊天室的訊息都同步。

所以後端的朋友責任會重一些,也因此才會有相應的套件產生吧?


參考資源

製作 WebSocket 客戶端應用程式

HTML5 WebSocket

ws: a Node.js WebSocket library

Summary
WebSocket 基本介紹及使用筆記
Article Name
WebSocket 基本介紹及使用筆記
Description
本篇大綱:WebSocket 前端得懂一點。WebSocket 重點心智圖。用 Node.js 建一個簡單的 WebSocket Server。前端連結 WebSocket。1 建立 WebSocket、2 監聽 WebSocket 事件、3 Client 端發訊息給 WS Server。
Augustus
Let's Write
Let's Write
https://letswrite.tw/wp-content/uploads/2020/08/logo_512.jpg
訂閱
通知
guest

1 Comment
最舊
最新
Inline Feedbacks
看所有留言
trackback
Firebase Realtime Database 常用功能筆記 - Google - Let's Write
5 月 之前

[…] 同場加映,之前寫過的 WebSocket 筆記文:WebSocket 基本介紹及使用筆記。 […]