架構設計模式:建立生產級的訂閱/發布架構
在小型專案中,我們常直接對所有連線進行廣播。但在大型系統中,這種暴力掃描會讓 CPU 瞬間滿載。
本章將引進專為即時通訊設計的 Pub/Sub (Publish/Subscribe) 模式與 房間 (Room) 概念。
一、 為什麼需要 Pub/Sub?
- 精準分發:只發送給感興趣的訂閱者。
- 解耦 (Decoupling):訊息發送者不需要知道接收者是誰。
- 可擴展性:為未來跨伺服器通訊鋪平道路。
二、 實戰演練:手寫 Room 管理器
我們不依賴 Socket.io,而是親手在 Node.js 中實作一個簡易的房間管理器。
核心代碼
javascript
class RoomManager {
constructor() {
this.rooms = new Map();
}
join(roomID, socket) {
if (!this.rooms.has(roomID)) this.rooms.set(roomID, new Set());
this.rooms.get(roomID).add(socket);
}
publish(roomID, message) {
const room = this.rooms.get(roomID);
if (!room) return;
const payload = JSON.stringify(message);
room.forEach((client) => client.send(payload));
}
}三、 架構演進:單機 vs 分散式
- 單機版:使用記憶體中的
Map。 - 分散式:使用 Redis Pub/Sub 作為中間層,達成跨伺服器通訊。
總結
良好的訊息架構是系統能支撐萬級甚至十萬級連線的關鍵。透過房間與頻道,我們能精確地掌控每一跳數據的去向。
下一章,我們將探討前端狀態管理:WebSocket 與 Pinia/React Hooks 同步。
️ 進階挑戰
- 實作挑戰:修改
RoomManager,讓一個 Socket 能夠同時加入「多個房間」。 - 效能思考:如果一個房間有 5000 人,每秒發送 10 條訊息,這會對 Node.js 的事件循環 (Event Loop) 造成什麼影響?
延伸閱讀與資源
- Patterns.dev:Pub-Sub Pattern
- Redis Docs:Pub/Sub mechanisms