跳至主要內容
Skip to content

架構設計模式:建立生產級的訂閱/發布架構

在小型專案中,我們常直接對所有連線進行廣播。但在大型系統中,這種暴力掃描會讓 CPU 瞬間滿載。

本章將引進專為即時通訊設計的 Pub/Sub (Publish/Subscribe) 模式與 房間 (Room) 概念。


一、 為什麼需要 Pub/Sub?

  1. 精準分發:只發送給感興趣的訂閱者。
  2. 解耦 (Decoupling):訊息發送者不需要知道接收者是誰。
  3. 可擴展性:為未來跨伺服器通訊鋪平道路。

二、 實戰演練:手寫 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 同步。


️ 進階挑戰

  1. 實作挑戰:修改 RoomManager,讓一個 Socket 能夠同時加入「多個房間」。
  2. 效能思考:如果一個房間有 5000 人,每秒發送 10 條訊息,這會對 Node.js 的事件循環 (Event Loop) 造成什麼影響?

延伸閱讀與資源