Node.js Socket.io:實現雙向即時通訊的完美方案

傳統的 HTTP 請求是由客戶端「發起」,伺服器「回應」的被動架構。但在開發聊天室、即時通知、金融行情或多人遊戲時,我們需要伺服端具備「主動推播 (Push)」訊息的能力。Socket.io 正是 Node.js 生態系中處理全雙工 (Full-duplex) 即時通訊的首選工具。

Socket.io vs 原生 WebSocket

雖然現代瀏覽器都支援原生 WebSocket,但 Socket.io 提供了更多企業級的功能:

  • 自動降級 (Fallback):若環境不支持 WebSocket,它會自動回退到 HTTP Long Polling,確保 100% 連線成功。
  • 自動重連:網路斷開時會自動嘗試恢復連線。
  • 房間 (Rooms) 與命名空間 (Namespaces):內建完整的連線分組管理邏輯。
  • 心跳檢測 (Heartbeat):自動偵測連線是否依然存活。

伺服器端實作:整合 Express

建立 Socket.io 服務時,必須將其掛載到一個原生 HTTP Server 實例上。

const express = require('express');
const { createServer } = require('http');
const { Server } = require('socket.io');

const app = express();
const httpServer = createServer(app); // 建立 HTTP Server 並傳入 Express
const io = new Server(httpServer); // 將 Socket.io 綁定到伺服器

io.on('connection', (socket) => {
  console.log(`新用戶連線:${socket.id}`);

  // 監聽來自客戶端的事件
  socket.on('send_message', (data) => {
    console.log('收到訊息:', data);

    // 廣播給「除自己以外」的所有人
    socket.broadcast.emit('receive_message', {
      user: socket.id,
      text: data.text,
    });
  });

  socket.on('disconnect', () => {
    console.log('用戶已中斷連線');
  });
});

// 注意:必須使用 httpServer.listen 而非 app.listen
httpServer.listen(3000, () => console.log('即時通訊伺服器運行中...'));

客戶端實作

<script src="/socket.io/socket.io.js"></script>
<script>
  const socket = io(); // 初始化連線

  function pushMessage() {
    socket.emit('send_message', { text: 'Hello Socket.io!' });
  }

  socket.on('receive_message', (data) => {
    console.log(`來自 ${data.user} 的訊息:${data.text}`);
  });
</script>

進階技巧:房間與命名空間

1. 房間機制 (Rooms)

適合開發群聊或特定頻道。

// 加入特定頻道
socket.join('room_id_101');

// 向該頻道內的所有人發送訊息
io.to('room_id_101').emit('announcement', '歡迎來到秘密頻道!');

2. 命名空間 (Namespaces)

如果你想把聊天邏輯與管理後台邏輯完全切開,可以使用命名空間:

const adminSpace = io.of('/admin');
adminSpace.on('connection', (socket) => {
  console.log('進入管理員專屬通道');
});
效能提醒:Socket.io 事件預設是可靠的。如果你在開發遊戲需要發送極高頻率且遺失也無妨的資料(如玩家座標),可以使用 socket.volatile.emit 來提升效能。

總結

  1. httpServer.listen 是整合 Express 時最容易出錯的地方。
  2. 善用 Rooms 實現精準的訊息投放,而不是無腦地廣播。
  3. Socket.io 大幅簡化了即時通訊的開發難度,它是構建互動式 Web 應用的關鍵。