使用 ServBay 建立與運行 Socket.io 專案
Socket.io 是一套廣受歡迎的 JavaScript 函式庫,專門為構建即時、雙向、事件驅動的網頁應用設計。它以 WebSocket 協議為基礎,並於必要時自動提供回退機制(如長輪詢),確保在各式瀏覽器與網路環境下實現穩定可靠的即時通訊。
本教學將帶您一步步利用 ServBay 強大靈活的本地開發環境來建立、運行與管理 Socket.io 專案。ServBay 提供預先配置的 Node.js 執行環境與高效的網站(原稱:主機)管理功能,讓 Socket.io 開發變得更輕鬆與高效。
什麼是 Socket.io?
Socket.io 是一個實現即時、雙向且以事件為核心的通訊機制的函式庫。它主要包含兩個部分:
- 一個運行於 Node.js 伺服器端的後端函式庫。
- 一個在瀏覽器中運作的前端 JavaScript 函式庫。
雖然 Socket.io 的主要目的是利用 WebSocket,但它可自動偵測並在需求時回退到其他傳輸方式(如 Adobe Flash Socket、Ajax Long Polling、Ajax Multipart Streaming、Forever IFrame、JSONP Polling 等),確保舊版瀏覽器或受限網路環境下的相容性。
Socket.io 的主要特性與優勢
- 即時通訊: 實現伺服器與用戶端間的即時資料交換,非常適合聊天室、協作工具、即時儀表板、線上遊戲等場景。
- 跨平台支援: 適用於 Web 瀏覽器、行動應用程序與 Node.js 伺服器環境。
- 自動重連: 當連線中斷時,客戶端會自動嘗試重新連接,提升應用的穩健性。
- 事件驅動: 以事件為核心的程式模型,讓非同步通訊邏輯清晰易管理。
- 房間與命名空間: 支援將客戶端歸類至「房間」以群組廣播訊息,「命名空間」則允許在單一連線上多路複用資源。
- 支援二進位資料: 可輕鬆傳送與接收二進位資料。
- 高相容性: 透過各種傳輸機制確保不同網路情境下的連線可靠性。
有了 Socket.io,開發人員可專注於應用邏輯,而不必煩惱底層即時通訊的實作細節。
使用 ServBay 建立與運行 Socket.io 專案
ServBay 為 Node.js 開發者提供一鍵啟用的本地開發環境,內建 Node.js 運行時、npm 套件管理器與方便的網站管理器。以下將示範如何利用這些工具設定和運行一個 Socket.io 範例專案。
前置準備
在開始之前,請先完成以下步驟:
- 安裝 ServBay: 從 ServBay 官方網站 下載並安裝最新版 ServBay。
- 於 ServBay 安裝 Node.js 套件: 請確認已於 ServBay 的【套件】(原稱:服務)功能下安裝 Node.js 套件。可於 ServBay 控制面板管理。更多說明請參考 在 ServBay 中使用 Node.js。
建立 Socket.io 範例專案
以下以一個簡易聊天室做範例。
初始化專案目錄:
請先開啟終端機。建議將網站專案存放於
/Applications/ServBay/www
。進入該資料夾後建立新專案資料夾,初始化 Node.js 專案及安裝所需套件:bashcd /Applications/ServBay/www mkdir servbay-socketio-chat cd servbay-socketio-chat npm init -y npm install express socket.io
1
2
3
4
5這會於
servbay-socketio-chat
產生一份package.json
,並安裝express
(用於靜態檔案與 HTTP 處理)與socket.io
(伺服器與用戶端套件)等核心依賴。新增伺服器檔案 (
server.js
):在
servbay-socketio-chat
專案目錄下建立server.js
,內容如下。該檔負責啟動 HTTP 伺服器,整合 Socket.io,並處理用戶連線與訊息廣播。javascriptconst express = require('express'); const http = require('http'); const socketIo = require('socket.io'); const path = require('path'); // 引入 path 模組 const app = express(); // 建立基於 express 應用的 HTTP 伺服器 const server = http.createServer(app); // 將 Socket.io 附加到 HTTP 伺服器 const io = socketIo(server); // 設定靜態檔案資料夾,指向當前目錄 app.use(express.static(__dirname)); // 處理根目錄 GET 請求,回傳 index.html app.get('/', (req, res) => { // 使用 path.join 確保跨作業系統路徑正常 res.sendFile(path.join(__dirname, 'index.html')); }); // 監聽 Socket.io 連線事件 io.on('connection', (socket) => { console.log('a user connected'); // 有新用戶連線時紀錄 log // 監聽斷線事件 socket.on('disconnect', () => { console.log('user disconnected'); // 用戶斷線時紀錄 log }); // 監聽 'chat message' 事件 socket.on('chat message', (msg) => { console.log('message: ' + msg); // 顯示收到的訊息 // 將訊息廣播給所有連線的用戶端 io.emit('chat message', msg); }); }); // 從環境變數或預設取得埠號 const port = process.env.PORT || 3000; server.listen(port, () => { console.log(`Server running on port ${port}`); console.log(`Access it via http://localhost:${port} (direct) or via ServBay reverse proxy`); });
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43程式碼說明:
- 使用
express
建立簡易 Web 伺服器,提供index.html
。 http.createServer(app)
產生標準 HTTP 伺服器作為 Socket.io 使用基礎。socketIo(server)
初始化並掛載 Socket.io 至伺服器。io.on('connection', ...)
監聽新用戶端連線。socket.on('disconnect', ...)
監聽離線事件。socket.on('chat message', ...)
監聽名為'chat message'
的訊息事件。io.emit('chat message', msg)
將訊息廣播給 所有 已連線的用戶端。
- 使用
新增用戶端檔案 (
index.html
):於根目錄建立
index.html
,內容如下。該檔包含 HTML 結構、樣式及 Socket.io 前端 JS,負責連接伺服器、傳送訊息與顯示所有訊息。html<!DOCTYPE html> <html> <head> <title>ServBay Socket.io Chat</title> <style> body { margin: 0; padding-bottom: 3rem; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; } #form { background: rgba(0, 0, 0, 0.15); padding: 0.25rem; position: fixed; bottom: 0; left: 0; right: 0; display: flex; height: 3rem; box-sizing: border-box; backdrop-filter: blur(10px); } #input { border: none; padding: 0 1rem; flex-grow: 1; border-radius: 2rem; margin: 0.25rem; } #input:focus { outline: none; } #form > button { background: #333; border: none; padding: 0 1rem; margin: 0.25rem; border-radius: 3px; outline: none; color: #fff; } #messages { list-style-type: none; margin: 0; padding: 0; } #messages > li { padding: 0.5rem 1rem; } #messages > li:nth-child(odd) { background: #efefef; } .servbay-banner { background-color: #007bff; /* ServBay 藍色 */ color: white; text-align: center; padding: 15px 0; font-size: 22px; margin-bottom: 20px; font-weight: bold; } </style> </head> <body> <div class="servbay-banner">歡迎體驗 ServBay Socket.io 聊天室示範!</div> <ul id="messages"></ul> <form id="form" action=""> <input id="input" autocomplete="off" /><button type="submit">傳送</button> </form> <!-- 載入 Socket.io 用戶端函式庫 --> <!-- 此檔案由 Socket.io 伺服器動態產生 --> <script src="/socket.io/socket.io.js"></script> <script> // 連線至 Socket.io 伺服器 // 若與伺服器同網域與埠號,io() 會自動連線 var socket = io(); var form = document.getElementById('form'); var input = document.getElementById('input'); var messages = document.getElementById('messages'); // 取得訊息清單元素 form.addEventListener('submit', function(e) { e.preventDefault(); // 阻止表單預設送出 if (input.value) { // 發送 'chat message' 事件與內容到伺服器 socket.emit('chat message', input.value); input.value = ''; // 清空輸入框 } }); // 監聽來自伺服器的 'chat message' 事件 socket.on('chat message', function(msg) { // 新增列表項顯示訊息 var item = document.createElement('li'); item.textContent = msg; // 用 textContent 防範 XSS messages.appendChild(item); // 新訊息加入列表 // 自動捲動至最新 window.scrollTo(0, document.body.scrollHeight); }); </script> </body> </html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64程式碼說明:
- 網頁含簡潔 HTML 結構、CSS 樣式(含品牌橫幅)、訊息列表 (
ul#messages
) 與傳送訊息表單 (form#form
)。 <script src="/socket.io/socket.io.js"></script>
載入 Socket.io 用戶端。此檔為伺服器啟動時自動產生,無須自行建立。io()
初始化並自動連上伺服器。- 用戶端監聽表單送出,阻止預設動作並呼叫
socket.emit('chat message', input.value)
傳送訊息。 - 客戶端監聽伺服器發送的
'chat message'
事件並顯示於頁面。
- 網頁含簡潔 HTML 結構、CSS 樣式(含品牌橫幅)、訊息列表 (
如此即完成 Socket.io 範例專案基本程式撰寫。接下來將整合 ServBay 運行並存取它。
以 ServBay 運作專案(開發模式)
開發階段通常直接運行 Node.js 伺服器,並透過 ServBay 反向代理綁定本地域名。
啟動 Node.js 開發伺服器:
開啟終端進入
/Applications/ServBay/www/servbay-socketio-chat
,以下指令啟動伺服器(本例監聽 8585 埠,可依需求調整):bashcd /Applications/ServBay/www/servbay-socketio-chat PORT=8585 node server.js
1
2啟動後終端會見到
Server running on port 8585
,此時伺服器監聽本地 8585 埠。於 ServBay 設定網站(反向代理):
如要方便以本地域名連線並啟用 HTTPS/SSL,可於 ServBay 新增反向代理網站:
- 開啟 ServBay 控制面板。
- 前往「網站」區(原稱:主機)。
- 點選【新增網站】。
- 設定建議如下:
- 名稱(Name):
ServBay Socket.io Dev
(或便於辨識的名) - 域名(Domains):
servbay-socketio-dev.servbay.demo
(或任一.servbay.demo
網域) - 網站類型(Type): 選
反向代理(Reverse Proxy)
- 代理目標(Proxy Destination): 填寫
http://127.0.0.1:8585
(指到此 Node.js 伺服器)
- 名稱(Name):
- 儲存設定。ServBay 會自動套用變更,並可能需自動重啟 Caddy 或 Nginx 伺服器(依您的 ServBay 設定而定)。
注意: 反向代理對 Socket.io 非常關鍵,除 HTTP 請求外,亦須處理 WebSocket 協議升級。ServBay 內建 Caddy 或 Nginx 已支援 WebSocket 代理。
詳細新增網站教學,請參考 新增 Node.js 開發網站。如需本地域名 HTTPS,請參見 使用 SSL/TLS 保護網站。ServBay User CA 與 ServBay Public CA 均可用於產生與信任本地 SSL 憑證。
開啟開發模式網址:
於瀏覽器打開您設置的本地域名
https://servbay-socketio-dev.servbay.demo
。應可見聊天室畫面,並於不同瀏覽器頁籤或裝置交互測試即時訊息。
以 ServBay 部署專案(生產模式)
生產環境時,建議透過 PM2 或 forever 等行程管理器背景執行 Node.js App,並與 ServBay 結合。下列僅示範反向代理設定,假設您的程式已在背景穩定運作於指定埠號。
啟動 Node.js 生產伺服器:
生產時常用行程管理器提升穩定性並自動重啟。以下以 PM2 為例:
bash# 若尚未安裝 PM2: # npm install pm2 -g cd /Applications/ServBay/www/servbay-socketio-chat PORT=8586 NODE_ENV=production pm2 start server.js --name servbay-socketio-prod
1
2
3
4
5如上將以 PM2 啟動
server.js
、設定 8586 埠與NODE_ENV
="production"。PM2 會將應用維持在背景運作。於 ServBay 設定生產網站(反向代理):
如同開發模式,新增一組反向代理網站指向伺服器運作的生產環境埠號。
- 開啟 ServBay 控制面板。
- 前往「網站」區。
- 新增網站。
- 建議如下:
- 名稱(Name):
ServBay Socket.io Prod
(或自訂辨識名) - 域名(Domains):
servbay-socketio-prod.servbay.demo
(或您的.servbay.demo
) - 網站類型(Type): 選
反向代理(Reverse Proxy)
- 代理目標(Proxy Destination): 指向
http://127.0.0.1:8586
(生產執行之埠號)
- 名稱(Name):
- 儲存設定。
開啟生產模式網址:
於瀏覽器開啟生產專用域名
https://servbay-socketio-prod.servbay.demo
。
透過 ServBay 的反向代理功能,您能輕易管理多個 Node.js 應用(無論開發或生產環境)、指派本地域名與 SSL 憑證,且免除手動更改 hosts 或複雜伺服器設定之苦。
連結 ServBay 提供的資料庫
ServBay 支援多種資料庫(如 MySQL、MariaDB、PostgreSQL、MongoDB、Redis)。您的 Socket.io 專案可透過這些資料庫儲存用戶資料、訊息紀錄等。以下皆為 Node.js 連線範例。
重要: 請於執行範例前,先確保已經從 ServBay 控制面板安裝並啟動目標資料庫套件。預設連線資訊(如埠號、使用者與密碼)可在 ServBay 資料庫管理介面或文件查得。例如 MySQL/MariaDB 的 root 預設密碼通常於安裝 ServBay 時設定。可於 ServBay 內重設 root 密碼。
連線 MongoDB:
安裝 Mongoose ODM(或官方
mongodb
驅動):bashnpm install mongoose
1在 Node.js 程式(如
server.js
或資料庫模組)加入連線:javascriptconst mongoose = require('mongoose'); // 預設連線至本機執行的 MongoDB(27017 為預設埠號),資料庫名稱 servbay_socketio_app 為範例 mongoose.connect('mongodb://localhost:27017/servbay_socketio_app', { useNewUrlParser: true, useUnifiedTopology: true, // 如需認證可加入 user, pass // user: 'your_mongo_user', // pass: 'your_mongo_password' }) .then(() => console.log('MongoDB 以 Mongoose 成功連線')) .catch(err => console.error('MongoDB 連線錯誤:', err)); // 現可透過 mongoose.model() 定義 Schema 與 Model // ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15連線 Redis:
安裝
redis
套件:bashnpm install redis
1加入 Redis 連線邏輯:
javascriptconst redis = require('redis'); // 建立 Redis 客戶端,預設連線至 localhost:6379 const client = redis.createClient({ // 若 Redis 有設定密碼: // password: 'your_redis_password', // url: 'redis://localhost:6379' // 亦可用 URL 格式 }); client.on('error', (err) => { console.error('Redis 連線錯誤:', err); }); client.on('connect', () => { console.log('Redis 客戶端連線成功'); }); // 開始連線 Redis client.connect(); // v4+ 必須顯式呼叫 connect() // 現可用 client 執行 Redis 指令 // 例如:await client.set('mykey', 'myvalue'); // ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23連線 MariaDB / MySQL:
ServBay 支援 MariaDB 與 MySQL。此以
mariadb
套件(同時支援 MySQL)示範:安裝
mariadb
:bashnpm install mariadb
1連線程式:
javascriptconst mariadb = require('mariadb'); // 建立連線池 const pool = mariadb.createPool({ host: 'localhost', port: 3306, // MariaDB/MySQL 預設埠號 user: 'root', // ServBay 預設用戶為 root password: 'password', // 填入您 ServBay 設定的 root 密碼 database: 'servbay_socketio_app', // 範例資料庫 connectionLimit: 5 // 連線池大小 }); // 取得連線並測試 pool.getConnection() .then(conn => { console.log("成功連線至 MariaDB/MySQL"); conn.release(); // 釋放回連線池 // 可使用 pool 執行查詢,例如:await pool.query("SELECT 1"); // ... }) .catch(err => { console.error("MariaDB/MySQL 連線錯誤:", err); });
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23注意: 請將
password
更換為您 ServBay 管理介面設定的 root 密碼。建議建立專用資料庫用戶,勿直接用 root。連線 PostgreSQL:
安裝
pg
套件:bashnpm install pg
1PostgreSQL 連線方式:
javascriptconst { Pool } = require('pg'); // 建立連線池 const pool = new Pool({ user: 'user', // PostgreSQL 預設為 user host: 'localhost', database: 'servbay_socketio_app', // 範例資料庫 password: 'password', // 您 ServBay 內設定的密碼 port: 5432, // PostgreSQL 預設埠 }); // 取連線並測試 pool.connect((err, client, done) => { if (err) { console.error('PostgreSQL 連線錯誤:', err); return; } console.log('成功連線 PostgreSQL'); client.release(); // 釋放回連線池 // 可用 pool 執行查詢,如:pool.query('SELECT NOW()', (err, res) => { ... }); // ... });
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22注意: 請替換
user
和password
為您於 ServBay 設定的用戶與密碼。
整合上述資料庫後,Socket.io 應用即可進行資料持久儲存,支援多元複雜應用開發。ServBay 讓本地建構 Node.js 與多種資料庫組合的開發環境變得前所未有地便捷。
注意事項
- 埠號衝突: 請確認您的 Node.js 程式監聽的埠(本例為 8585 或 8586)未被其它程式佔用。若有衝突可調整
PORT
環境變數。 - ServBay 網站設定: 設定反向代理網站後,請確認 ServBay 的 Web 伺服器(Caddy 或 Nginx)已重新啟動套用新設定。
- WebSocket 代理: ServBay 反向代理預設支援 WebSocket。若遇連線問題,請檢查伺服器日誌或設定是否支援 WebSocket。
- 防火牆設置: 請確保作業系統防火牆未阻擋 ServBay 用之(如 80、443)或 Node.js 伺服器監聽的埠號。