基本WebSocket聊天室後端示範

更新於 發佈於 閱讀時間約 16 分鐘

※ 先建立基本的express後端服務:

1.建立新資料夾:WebSocket

mkdir websocket

2.進入資料夾:WebSocket

cd ​websocket

3. 安裝 Experss 到專案中

npm init -y //初始化專案,建立 package.json 檔
npm install express

4.在 package.json 中type預設使用 CommonJS 模式改為 module

 "keywords": [],
  "author": "",
  "license": "ISC",
  "type": "module",
  "description": "",
  "dependencies": {
    "express": "^5.1.0"
  }

5.修改腳本

"scripts": {
"start": "node index.js",
"dev": "nodemon index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},

6.建立index.js:寫入基本的伺服器程式碼。

import express from 'express';
import http from 'http';

const app = express();
const server = http.createServer(app);
// 提供靜態檔案服務
app.use(express.static('public'));
// 定義路由
app.get('/hello', (_, res) => {
  res.send('Hello World');
  res.end();
});
// 啟動伺服器
server.listen(8080, () => {
  console.log('Server started on port 8080');
});

7.啟動express

npm run dev
raw-image

8.建立靜態資料夾:public --> index.html

<!DOCTYPE html>
<html>

<head>
<title>WebSocket minimal demo</title>
</head>

<body>
<p>index.html</p>
</body>

</html>

※ 建立基本的websocket伺服器:

1.引用websocket相關套件

npm install ws

2.index.js中引入

import { WebSocketServer } from 'ws';
...
// 創建websocket伺服器
const wss = new WebSocketServer({ server });

程式碼解說:

const wss = new WebSocketServer({ server })優點:

  • WebSocket 伺服器可以與 HTTP/HTTPS 共用同一個埠,節省系統資源。
  • 允許同一個端口既處理 HTTP/HTTPS 請求,也能支持 WebSocket 通訊。

※ 建立Server規則:

用來作為 WebSocket 應用程式的基礎,並實現雙向即時通信,例如聊天應用程式或通知系統。

wss.on('connection', ws => {
  //收到訊息後要做的事
  ws.on('message', message => {
    //發送一個log到後端的終端
    console.log('Received:' + message.toString());
  });
  //對著連接發送訊息
  ws.send('Hello');
})

程式碼解說:

1.wss.on('connection', ws => {...}):

  • wss是 WebSocket 伺服器,這行程式表示每當有新的客戶端(Client)連接到伺服器時,將執行指定的回呼函式。
  • 回呼函式的參數 代表單一連接的 WebSocket 實例(Instance),用於處理該特定連接的操作。

2.ws.on('message', message => {...});:

  • 這行程式表示每當伺服器端收到從客戶端發來的訊息()時,執行指定的回呼函式。
  • 回呼函式內的 將收到的二進制訊息轉換為字串。
  • 使用 將訊息記錄到伺服器的終端機(Console)。

3.ws.send('Hello'):

  • 對當前 WebSocket 連接的客戶端發送字串訊息 「Hello」。
  • 每次連接時,伺服器會主動向客戶端發送此訊息。

※ 透過Postman測試連線:

  • 開啟Postman → NEW建立新專案 → 選擇WebSocket
raw-image
  • 輸入端口:8080
raw-image
  • 連線成功WebSocket:
raw-image
  • 從前端發送訊息:Hi
raw-image
  • 後端收到前端發送的訊息:
raw-image

※ 實現WebSocket的特性範例:雙向溝通

使用setInterval函數:固定某一段時間不斷發送一個訊息。

setInterval(() => {
//呼叫websocket
wss.clients.forEach(client => {
client.send('Hi');
})
}, 1000);

程式碼解說:

1.setInterval(() => {...}, 1000);:

  • setInterval是用來定期執行某段程式碼的函式,也就是定時器。
  • 這裡的箭頭函式會每隔 1000 毫秒(1 秒)執行一次,也就是每隔一秒就會執行一段程式。

2.wss.clients:

  • wss是 WebSocket 伺服器的實例。
  • wss.clients是目前所有已連線客戶端(WebSocket 連接)的集合。

3.wss.clients.forEach(client => {...}):

  • 迭代當前所有連線的客戶端。
  • 每個client 都代表一個連線的 WebSocket 實例。

4.client.send('Hello'):

  • 使用 WebSocket 的 方法,向該特定客戶端發送字串訊息 'Hello'。

當後端關機時和前端所的連結就會被切斷,就會出現Disconnected訊號:

raw-image

重新連結:

raw-image

成功連結:

raw-image

對話回覆:

raw-image

※ 建立聊天室首要任務:區分用戶連線

建立群組聊天室:

ws.on('message', message => {
//轉發訊息給所有人
wss.clients.forEach(client => {
//後端伺服器留紀錄
console.log(ws.id + message.toString());
client.send(ws.id + message.toString());
});
});

程式碼解說:

1.ws.on('message', message => {...});:

  • 這行程式表示每當伺服器端收到從客戶端發來的訊息()時,執行指定的回呼函式。
  • 回呼函式內的 將收到的二進制訊息轉換為字串。
  • 使用 將訊息記錄到伺服器的終端機(Console)。

2.wss.clients.forEach(client => {...}):

  • wss.clients是目前所有已連線客戶端(WebSocket 連接)的集合。
  • 迭代當前所有連線的客戶端。
  • 每個client 都代表一個連線的 WebSocket 實例。

3.console.log(ws.id + message.toString()):

  • 將接收到的訊息內容輸出到伺服器的終端機(Console),方便開發者或系統管理員檢查訊息記錄。
  • 用ws.id 來告訴接收端這個訊息是來自哪個客戶端。

4.client.send(ws.id + message.toString()):

  • 用ws.id 來告訴接收端這個訊息是來自哪個客戶端。
  • 使得所有連線的用戶都能接收到來自任何其他使用者的訊息。

連線結果:

raw-image

建立第二個連線用戶:

raw-image

聊天室雛型:

raw-image

將每個連線去做一個標示:

wss.on('connection', ws => { 
  //將每個連線去做一個標示:
  ws.id = Math.round(Math.random() * 100);//產生0~100隨機數字
  //對著連接發送訊息
  ws.send('Hello, your id is' + ws.id);
...})

程式碼解說:

1.為新連線分配一個唯一標示:

ws.id = Math.round(Math.random() * 100);
  • ws.id:當前連線的 WebSocket 客戶端設置一個標示,用於識別該連線。
  • Math.random() * 100:將隨機小數放大為0 至100 之間的隨機浮點數。
  • Math.round():將浮點數四捨五入為整數,得到範圍在0 至 100 之間的隨機數字。

2.向客戶端發送訊息:

ws.send('Hello, your id is ' + ws.id);
  • 客戶端可以通過接收此訊息獲得自己的唯一 id。

3.連線成功客戶端的id:

raw-image

群組聊天室基本架構結果:

raw-image

建立密語功能:只對某人傳訊息

if (msg.split(' ')[0] === '/m') {
const parts = msg.split(' ');

// 確保命令格式正確
if (parts.length < 3) {
console.error('格式錯誤:請使用 "/m <target> <message>"');
ws.send('格式錯誤:請使用 "/m <target> <message>"');
return;
}

const target = parseInt(parts[1], 10);

// 檢查目標是否為有效數字
if (isNaN(target)) {
console.error(`錯誤:目標 ID 必須是數字,接收到:${parts[1]}`);
ws.send(`錯誤:目標 ID 必須是數字,接收到:${parts[1]}`);
return;
}

const message = parts[2]; // 只取第三部分當訊息
let clientFound = false;

wss.clients.forEach(client => {
if (client.id === target) {
clientFound = true;
console.log(`[m] ${ws.id} says ${message}`);
client.send(`[m] ${ws.id} says ${message}`);
}
});

if (!clientFound) {
console.error(`未找到目標客戶端 ID:${target}`);
ws.send(`未找到目標客戶端 ID:${target}`);
}
return;
}

程式碼解說:

1.檢查指令是否是 /m:

if (msg.split(' ')[0] === '/m') {}
  • 接收到的msg 是否以/m 開頭,如果不是 ,程式會跳過此邏輯。

2.分割命令內容:

const parts = msg.split(' ');

使用split 分割字符串,將空格作為分隔符。分割後, parts是一個數組:

  • parts[0]是指令本身 。
  • parts[1]是目標 ID 。
  • parts[2]是要發送的訊息 。

3.檢查命令格式是否正確:

if (parts.length < 3) {
console.error('格式錯誤:請使用 "/m <target> <message>"');
ws.send('格式錯誤:請使用 "/m <target> <message>"');
return;
}
  • 如果分割後的數組長度不足 3,表示命令格式錯誤(例如缺少目標 ID 或訊息),程式會提示並結束執行。
raw-image


4.提取目標 ID 並轉換為數字:

const target = parseInt(parts[1], 10);
if (isNaN(target)) {
console.error(`錯誤:目標 ID 必須是數字,接收到:${parts[1]}`);
ws.send(`錯誤:目標 ID 必須是數字,接收到:${parts[1]}`);
return;
}
  • 使用parseInt 將目標 ID 轉換為數字。如果轉換失敗(NaN),程式會報錯並結束執行。
  • parseInt用來將字符串(string)轉換為整數(integer)。它經常被用於需要從字符串中提取數字的場合。
raw-image


5.提取訊息內容:

const message = parts[2];
  • 從分割數組中提取訊息內容,這是用戶希望發送的消息。


6.搜尋目標客戶端並發送消息:

let clientFound = false;
wss.clients.forEach(client => {
if (client.id === target) {
clientFound = true;
console.log(`[m] ${ws.id} says ${message}`);
client.send(`[m] ${ws.id} says ${message}`);
}
});
  • 這段程式碼會遍歷所有的 WebSocket 客戶端(wss.clients),找到 ID 與目標匹配的客戶端並發送消息。
  • 如果找到匹配的客戶端,會將消息發送給該客戶端。
  • 並且會將操作結果記錄在伺服器日誌中。

7.處理找不到目標客戶端的情況:

if (!clientFound) {
console.error(`未找到目標客戶端 ID:${target}`);
ws.send(`未找到目標客戶端 ID:${target}`);
}
  • 如果在遍歷中未找到目標客戶端,程式會報錯並通知發送消息的用戶。

8.結束執行:使用return 結束執行,避免繼續後續邏輯。

結果:

raw-image





留言
avatar-img
留言分享你的想法!
avatar-img
奧莉薇走在成為後端工程師之路上
18會員
141內容數
全端網頁開發專業知識分享
2025/04/26
※ 場景: 即時聊天應用: 設計一個支持多房間功能的即時聊天平台,像 WhatsApp、LINE或Facebook Messenger,提供文字、語音、視訊聊天功能,方便管理群組聊天。 功能亮點:加入特別功能,例如可加入多房間功能、使用者名單、表情符號支持、文件分享或訊息已讀未讀狀態。 展示
2025/04/26
※ 場景: 即時聊天應用: 設計一個支持多房間功能的即時聊天平台,像 WhatsApp、LINE或Facebook Messenger,提供文字、語音、視訊聊天功能,方便管理群組聊天。 功能亮點:加入特別功能,例如可加入多房間功能、使用者名單、表情符號支持、文件分享或訊息已讀未讀狀態。 展示
2025/04/26
※ 先建立基本的express後端服務: 1.建立新資料夾:Socket mkdir socket 2.進入資料夾:Socket cd ​bsocket 3. 安裝 Experss 到專案中 npm init -y //初始化專案,建立 package.json 檔 npm insta
Thumbnail
2025/04/26
※ 先建立基本的express後端服務: 1.建立新資料夾:Socket mkdir socket 2.進入資料夾:Socket cd ​bsocket 3. 安裝 Experss 到專案中 npm init -y //初始化專案,建立 package.json 檔 npm insta
Thumbnail
2025/04/10
※ 什麼是 Socket.io:一個基於傳統 WebSocket API 之上的框架。 ※ Socket.io常用功能: Custom Events:在 Socket.io 中,開發者可以創建自己的事件來處理特定的功能或需求。 Rooms:分組的功能。每個連接的用戶(或稱為 socket)可
Thumbnail
2025/04/10
※ 什麼是 Socket.io:一個基於傳統 WebSocket API 之上的框架。 ※ Socket.io常用功能: Custom Events:在 Socket.io 中,開發者可以創建自己的事件來處理特定的功能或需求。 Rooms:分組的功能。每個連接的用戶(或稱為 socket)可
Thumbnail
看更多
你可能也想看
Thumbnail
每年4月、5月都是最多稅要繳的月份,當然大部份的人都是有機會繳到「綜合所得稅」,只是相當相當多人還不知道,原來繳給政府的稅!可以透過一些有活動的銀行信用卡或電子支付來繳,從繳費中賺一點點小確幸!就是賺個1%~2%大家也是很開心的,因為你們把沒回饋變成有回饋,就是用卡的最高境界 所得稅線上申報
Thumbnail
每年4月、5月都是最多稅要繳的月份,當然大部份的人都是有機會繳到「綜合所得稅」,只是相當相當多人還不知道,原來繳給政府的稅!可以透過一些有活動的銀行信用卡或電子支付來繳,從繳費中賺一點點小確幸!就是賺個1%~2%大家也是很開心的,因為你們把沒回饋變成有回饋,就是用卡的最高境界 所得稅線上申報
Thumbnail
這篇文章介紹了網站的整體架構以及開發時所使用的工具和套件,包括 Next.js、Tailwind CSS 和 socket.io 等。文章回顧了程式碼的重構與優化,幫助開發者提高工作效率,適合希望深入瞭解前端開發和網站架構的讀者。
Thumbnail
這篇文章介紹了網站的整體架構以及開發時所使用的工具和套件,包括 Next.js、Tailwind CSS 和 socket.io 等。文章回顧了程式碼的重構與優化,幫助開發者提高工作效率,適合希望深入瞭解前端開發和網站架構的讀者。
Thumbnail
你好,在下最近在學習開發web,學了html css js,也得出一些心得,由於網路上已有許多教學,所以我會著重在如何開發出to do List,以及解釋我寫的程式碼。相關的教學我會直接貼網址。如果我有什麼地方出錯,或者是可以寫得更好,歡迎在下方留言,討論。 首先先介紹我的開發環境: 我用了vs
Thumbnail
你好,在下最近在學習開發web,學了html css js,也得出一些心得,由於網路上已有許多教學,所以我會著重在如何開發出to do List,以及解釋我寫的程式碼。相關的教學我會直接貼網址。如果我有什麼地方出錯,或者是可以寫得更好,歡迎在下方留言,討論。 首先先介紹我的開發環境: 我用了vs
Thumbnail
前面已經安裝好IIS後,並且也新建站台了,那麼接下來這篇就會分享如何使用它
Thumbnail
前面已經安裝好IIS後,並且也新建站台了,那麼接下來這篇就會分享如何使用它
Thumbnail
接續上一篇 Step2:VC#專案建立 Step3:IIS新建站台 Step4:VC#架設到IIS中
Thumbnail
接續上一篇 Step2:VC#專案建立 Step3:IIS新建站台 Step4:VC#架設到IIS中
Thumbnail
  在開始操作Web Service之前,要先做一些前置作業IIS的安裝,再開始建置Web Service相關內容,最後就是連線測試。   IIS(Internet Information Services)是網際網路資訊服務,可以讓網站使用HTTP/HTTPS、FTP/FTPS、SMTP 等等的
Thumbnail
  在開始操作Web Service之前,要先做一些前置作業IIS的安裝,再開始建置Web Service相關內容,最後就是連線測試。   IIS(Internet Information Services)是網際網路資訊服務,可以讓網站使用HTTP/HTTPS、FTP/FTPS、SMTP 等等的
Thumbnail
前段時間我們有介紹「【Python 軍火庫🧨 - websockets】雙向溝通的渠道」, 這種方式可以達到基本的連線沒問題,但隨著資安意識的抬頭, 我們的websocket連線也會需要在通道之上進行加密, 那麼我們將根據使用情境來教您如何選用適當的連線。 Server端 我們的Serve
Thumbnail
前段時間我們有介紹「【Python 軍火庫🧨 - websockets】雙向溝通的渠道」, 這種方式可以達到基本的連線沒問題,但隨著資安意識的抬頭, 我們的websocket連線也會需要在通道之上進行加密, 那麼我們將根據使用情境來教您如何選用適當的連線。 Server端 我們的Serve
Thumbnail
Express 是一個流行的 web 框架,使用 JavsScript 實現,執行在 node 環境上,主要用來寫後端應用。
Thumbnail
Express 是一個流行的 web 框架,使用 JavsScript 實現,執行在 node 環境上,主要用來寫後端應用。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News