iT邦幫忙

2024 iThome 鐵人賽

DAY 17
0
自我挑戰組

30 天 Node.js 探索:基礎、進階與實踐系列 第 17

Day 17: 使用 WebSocket 實現即時通訊

  • 分享至 

  • xImage
  •  

接下來要學習如何使用 WebSocket 在 Node.js 應用程式中實現即時通訊,了解它跟 HTTP 協議的差異,以及如何處理雙向資料傳輸。

WebSocket 簡介

WebSocket 是一種全雙工協議,它允許在單一 TCP 連接上進行雙向通信,實現伺服器與客戶端之間的即時數據傳輸。這與傳統的 HTTP 不同,HTTP 是基於請求與回應模式的,資料傳輸受限於客戶端請求。

WebSocket 的特點

  • 全面雙向通信: 伺服器和客戶端可以在任意時間互相傳送訊息,不需要每次請求。
  • 低延遲: 適合用於需要即時互動的應用程式,如即時聊天、遊戲、即時通知等。
  • 持續連接: 一次連接建立後,雙方可以持續進行溝通,減少了連接的開銷。

HTTP 與 WebSocket 的區別

  • HTTP: 基於請求-回應的模式,客戶端每次需要資料時都必須向伺服器發送請求。
  • WebSocket: 建立連接後,伺服器可以主動向客戶端發送資料,無需等待客戶端請求。

建立 WebSocket 伺服器

在 Node.js 中,使用 ws 套件就可以輕鬆建立 WebSocket 伺服器。

安裝 WebSocket 套件

bash
npm install ws

創建簡單的 WebSocket 伺服器

接著要使用 ws 套件來建立一個簡單 WebSocket 伺服器:

js
const WebSocket = require('ws');

// 創建 WebSocket 伺服器,監聽在 8080 埠
const wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', (ws) => {
  console.log('New client connected');

  // 接收來自客戶端的訊息
  ws.on('message', (message) => {
    console.log('Received:', message);

    // 回應客戶端的訊息
    ws.send(`Server received: ${message}`);
  });

  // 當連接關閉時
  ws.on('close', () => {
    console.log('Client disconnected');
  });
});

console.log('WebSocket server is listening on ws://localhost:8080');

實際打入 Node.js ,執行結果會如下:
https://ithelp.ithome.com.tw/upload/images/20240930/20169444mkWxxDE7Pn.png

建立 WebSocket 客戶端

在客戶端可以使用原生的 WebSocket API,或是只要可以支援 WebSocket 的工具與伺服器就能通訊。

在前端創建 WebSocket 連接

HTML 客戶端的範例:

html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>WebSocket Client</title>
</head>
<body>
  <h1>WebSocket Demo</h1>
  <input id="messageInput" type="text" placeholder="Type a message..." />
  <button onclick="sendMessage()">Send</button>
  <div id="messages"></div>

  <script>
    // 建立 WebSocket 連接
    const socket = new WebSocket('ws://localhost:8080');

    socket.onopen = () => {
      console.log('Connected to server');
    };

    socket.onmessage = (event) => {
      const messages = document.getElementById('messages');
      messages.innerHTML += `<p>Received: ${event.data}</p>`;
    };

    socket.onclose = () => {
      console.log('Disconnected from server');
    };

    function sendMessage() {
      const input = document.getElementById('messageInput');
      const message = input.value;
      socket.send(message);
    }
  </script>
</body>
</html>

這個客戶端將連接到 ws ://locoalhost,並可以向伺服器發送訊息,伺服器會回傳收到的訊息,並顯示在頁面上。
實際執行 html ,並開啟瀏覽器後的結果:
https://ithelp.ithome.com.tw/upload/images/20240930/201694440tThcDsbRD.png
接著輸入文字後,會像下圖顯示已成功發送回伺服器:
https://ithelp.ithome.com.tw/upload/images/20240930/201694445hsgU80Jc2.png
最後回伺服器端,即可看到在瀏覽器輸入的數值:
https://ithelp.ithome.com.tw/upload/images/20240930/20169444CeF7Sd1gEC.png

使用 WebSocket 的場景

WebSocket 最常用於需要即時資料傳輸的場景,下面說幾個比較常見的時機:

  • 即時聊天應用: 用於實時通訊,雙方可以在同一連接中即時發送訊息。
  • 即時遊戲: 玩家與伺服器的即時互動,像是多人線上遊戲。
  • 股票報價或數據流: 持續地傳送數據更新給用戶端,這樣就不用頻繁請求伺服器。
  • 即時通知系統: 例如新消息通知或系統提醒。

處理多客戶端連接

WebSocket 伺服器能同時處理多個客戶端的連接,當有多個使用者連接到伺服器時,可以廣播訊息給所有客戶端或處理特定客戶端的訊息。

廣播訊息給所有客戶端

將訊息發送給所有已連接客戶端的範例:

js
wss.on('connection', (ws) => {
  ws.on('message', (message) => {
    // 廣播訊息給所有客戶端
    wss.clients.forEach((client) => {
      if (client.readyState === WebSocket.OPEN) {
        client.send(`Broadcast: ${message}`);
      }
    });
  });
});

這段程式碼會將每個客戶端發送的訊息廣播給所有已連接的客戶端。

WebSocket 的錯誤處理

在處理即時連接的時候,出現錯誤和連接的中斷是很常見的問題。WebSocket 提供了錯誤事件,讓開發者能夠應對這些情況。

錯誤處理範例

js
ws.on('error', (err) => {
  console.error('WebSocket error:', err);
});

當連接發生錯誤時,可以通過這個事件來捕捉並記錄錯誤。

總結

今天學習了如何在 Node.js 中使用 WebSocket 實現即時通訊。通過 WebSocket 協議,伺服器和客戶端可以實現低延遲的雙向通訊,適用於各類需要即時互動的應用場景。在後續的開發中,可以將 WebSocket 應用於聊天系統、遊戲、通知系統等場景,提升應用的互動性和使用者體驗。


上一篇
Day 16:安全性最佳實踐:避免 SQL Injection 和 XSS
下一篇
Day 18: 部署 Node.js 應用程式至 Heroku
系列文
30 天 Node.js 探索:基礎、進階與實踐30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言