參考文章
💓使用MongoDB結合Express和Fetch來實作RESTful API簡單網站(包括用戶Post, Get, Update, Delete等功能)
💓基礎>>使用WebSocket結合node.js實作一個線上聊天室,只需要3個檔案就完成
💓進階>>使用WebSocket結合node.js實作一個線上聊天室(進階功能:即時時間動態顯示,表情符號emoji等)
💓超進階>>使用WebSocket結合vue.js實作一個程式碼簡單明瞭的線上聊天室
參考外部文章
💓淺談 WebSocket 協定:實作一個簡單的即時聊天室吧!
├── front.js
👄😉
Q: 為何需要require('http')和http.createServer(app)呢?
A: 在之前的程式碼中,使用 const express = require('express'); 和 const app = express();
是用來建立一個 Express 應用程式。Express 是一個 Node.js 的 Web 應用程式框架,
它提供了簡潔的 API 讓開發者能夠輕鬆建立基於 Node.js 的 Web 伺服器。
在一般的情況下,如果只需要建立一個基本的 Web 伺服器,並不需要額外地使用 WebSocket
或其他更高級的通訊協議。因此,在一開始只使用 Express 時,
僅需使用 const express = require('express'); 和 const app = express();
就足夠建立一個基本的 HTTP 伺服器,可以處理網頁請求、路由、中間件等等。
但是,當你想要在同一個伺服器上實現 WebSocket 功能時,
Express 本身無法直接處理 WebSocket 的通訊。所以,為了在同一個伺服器上實現 WebSocket 功能,
需要使用 Node.js 原生的 HTTP 模組來建立底層的 HTTP 伺服器,以便與 WebSocket 進行整合,
這也是為什麼在原先的程式碼中引入了 const http = require('http');
並且使用 http.createServer(app) 的原因。
這樣做可以將 Express 應用程式集成到 Node.js 的 HTTP 伺服器中,
以便在同一伺服器上處理HTTP 請求和 WebSocket 連接。
>>簡單來說,當你需要在同一個伺服器上實現基於 HTTP 和 WebSocket 的通訊時,
就需要使用到 Node.js 的 HTTP 模組來建立底層的 HTTP 伺服器,
然後將 Express 應用程式整合到該伺服器中,以支援這兩種不同的通訊方式。
👄😉
wss.on 和 ws.on 是用來設置事件監聽器(event listener)的方法,但它們應用在不同的對象上。
1. wss 是 WebSocket Server 的實例,在伺服器端用於監聽客戶端與伺服器建立的 WebSocket 連接。
2. ws 則是單一 WebSocket 連接的實例,它代表伺服器與單一客戶端之間的一個連接。
具體來說:
1. wss.on(event, callback) 用於在 WebSocket Server 實例上設置事件監聽器,當特定事件發生時
(例如 'connection'),就會執行對應的回調函式(callback)。
這是用來管理伺服器上多個 WebSocket 連接的事件。
2. ws.on(event, callback) 則是在單一 WebSocket 連接實例上設置事件監聽器,
用於處理特定 WebSocket 連接的事件,
例如當單一連接收到訊息時觸發 'message' 事件,或者當連接關閉時觸發 'close' 事件。
>>簡單來說來說,wss.on 用於 WebSocket 伺服器端,用來管理多個連接的事件處理,
而 ws.on 則是在每個單一的 WebSocket 連接上用來處理該連接的事件。
👄😉
這裡是在 WebSocket 伺服器 (wss) 上的所有客戶端 (wss.clients) 上遍歷進行操作。對於每個客戶端,程式碼檢查以下條件:
client !== ws: 確保當前訊息不發送給原始發送訊息的那個客戶端。
client.readyState === WebSocket.OPEN: 確保客戶端的連接狀態是開啟的
(即 WebSocket.OPEN 狀態),這樣才能透過 WebSocket 連接發送訊息。
如果滿足這兩個條件,就會將 message 透過 client.send(message) 發送給該客戶端。
Q: wss.clients是?
A: 當使用 wss.on('connection', function connection(ws) {...}) 設置新連接時的事件監聽器時,
當有新的 WebSocket 客戶端連接到伺服器時,這個 wss.clients 屬性會自動更新,
將新的客戶端 WebSocket 實例加入到這個集合中。
透過 wss.clients 屬性,你可以迭代這個集合,例如使用 forEach 方法,來遍歷所有的連接客戶端,
進而對所有連接做相應的操作,例如廣播訊息給所有客戶端。
這種用法允許伺服器與所有連接的客戶端進行交互動作。
👄😉
client.readyState 是 WebSocket 物件的屬性,用來表示該 WebSocket 連接的當前狀態。它可以是以下幾個值之一:
- WebSocket.CONNECTING (0):連接尚未建立。
- WebSocket.OPEN (1):連接已建立且可以通訊。
- WebSocket.CLOSING (2):連接正在關閉。
- WebSocket.CLOSED (3):連接已經關閉或無法建立。
WebSocket.OPEN 是 WebSocket 物件的常數,代表 WebSocket 連接已建立且可以通訊的狀態值,它的值是整數 1。
client.readyState 屬性代表 WebSocket 連接的當前狀態,可能的值是 0、1、2 和 3,
分別對應著 WebSocket.CONNECTING、WebSocket.OPEN、WebSocket.CLOSING 和 WebSocket.CLOSED。每個值對應著不同的連接狀態,可以用來判斷連接目前的狀態
在以上程式碼片段中,client.readyState === WebSocket.OPEN 這個條件語句檢查的是該 WebSocket 連接是否處於可以通訊的狀態,如果是的話,表示該連接目前是開啟的狀態,可以進行資料傳輸。
Q: 如果您發現這段程式碼中的訊息沒有被傳送到任何一個客戶端,請確保:
A: 您有多個客戶端已經連接到伺服器。是否加了client !== ws && 代表訊息不傳給自己。
如果想要訊息也傳給自己的話,請把client !== ws && 拿掉。
可以看到message有『送出』和『接收』到。
front.js
在JavaScript中,當您使用new關鍵字來創建新的物件時,您需要提供一個類(class)
或者構造函數(constructor function)。
在程式碼中,WebSocket是瀏覽器提供的內建類,用於建立WebSocket連接。
當使用new WebSocket('ws://localhost:3000')時,JavaScript會知道WebSocket是要創建的物件類別,
並使用指定的URL來建立到該URL的WebSocket連接。
對於Schema,它不是JavaScript的內建類或構造函數。Schema來自於Mongoose這個庫(Library),
它是Mongoose庫提供的類(class)或者構造函數(constructor function)。
因此,當需要使用Schema時,您必須首先透過mongoose.Schema來訪問和建立它,
以便使用它來定義資料庫中的模型結構。
JavaScript本身提供了一些內建的物件或類(如Array、Object等),
可以直接使用它們來創建新的物件。
而對於像Mongoose這樣的庫所提供的類(如Schema),需要通過該庫提供的方式來訪問和使用它。
這些事件屬於 WebSocket 物件的屬性,並且它們具有特定的名稱,不是任意命名的。
這些名稱都是固定的,在使用 WebSocket 時,您可以依賴這些名稱來處理不同的事件。
例如,onopen 事件是用來處理 WebSocket 連接成功時的情況,
onmessage 事件用來處理接收到訊息的情況,onclose 事件用來處理連接關閉的情況。
當 socket.send() 被呼叫時,資料將會透過 WebSocket 連接被傳送到伺服器端,
您可以在後端的 WebSocket 伺服器程式中處理這些資料。
可以看出在網頁的console中,event, event.data, JSON.parse(event.data)的差別。
藉由JSON.parse過後的data呼叫的data.name和data.message訊息為最乾淨的。
假如有兩個人分別為「拉拉」和「蓮花」,
沒有留言:
張貼留言
喜歡我的文章嗎? 喜歡的話可以留言回應我喔! ^^