※ 什麼是 Socket.io:一個基於傳統 WebSocket API 之上的框架。
※ Socket.io常用功能:
- Custom Events:在 Socket.io 中,開發者可以創建自己的事件來處理特定的功能或需求。
- Rooms:分組的功能。每個連接的用戶(或稱為 socket)可以加入一個或多個房間,也可以離開房間。
- Namespace (multiplexing):Namespace (命名空間) 是在一條連線(connection)上劃分出多個“區域”,每個區域都有自己獨立的狀態與處理邏輯。
- Redis Support:支援Redis的技術。Redis是一個高性能的開源內存數據庫,主要用於Key-Value存取。
- Ack:"Acknowledgment" 的縮寫,廣泛用於多個領域,但通常表示確認或回應,是一種通信上的技術。
- Auto reconnect:自動重新連線。
- Fallback transport:當主要的傳輸方法失敗時,系統會使用備選的傳輸方法來確保郵件能夠送達。
- Volatile Events:是一種特殊的事件類型,當底層連接未準備好時,這些事件可能不會被傳送。這種設計類似於 UDP 協議的可靠性,適用於某些即使丟失數據也不會影響應用的場景,例如線上遊戲。
※ Custom Events介紹:客製化事件,開發者根據特定應用場合,自行定義的事件。
- 客製化設計:根據不同的場合(例如聊天訊息、新用戶加入、錯誤通知)去設計不同的event(事件)。
第一組範例:
//伺服器端
io.on("connection", (socket) => {
socket.emit("hello", "world");
});
//客戶端
socket.on("hello", (arg) => {
console.log(arg); // world
});
程式碼說明:
伺服器向客戶端發送了"hello" 事件,並帶有字串"world" 作為參數。客戶端接收到這個事件後,打印了"world" 。
- 傳遞參數:事件的觸發可以同時傳不同的參數進來,這些參數通常是與事件相關的數據,例如時間戳、用戶資訊或操作詳情。
第二組範例:
//伺服器端
io.on("connection", (socket) => {
socket.emit("hello", 1, "2", { 3: '4', 5: Buffer.from([6]) });
});
//客戶端程式碼說明:
socket.on("hello", (arg1, arg2, arg3) => {
console.log(arg1); // 1
console.log(arg2); // "2"
console.log(arg3); // { 3: '4', 5: ArrayBuffer (1) [ 6 ] }
});
伺服器向客戶端發送事件時,可以傳遞多個參數,包括數字、字串和物件。客戶端正確地接收並打印了這些參數的值。

※ Rooms:分組通信。
- 這張圖片展示了如何使用「Rooms」功能進行分組通信。它表明伺服器可以將某些連線(sockets)分配到特定的房間(如「myroom」),使得該房間內的用戶能夠相互通信,而不影響其他房間。

※ Namespace:命名空間。
架構圖解:
- Client 部分包含兩個框:
Default namespace
和Admin namespace
。 - 中間是 one single pipe,代表客戶端與伺服器之間的一個連線。
- Server 部分同樣包含兩個框:
Default namespace
和Admin namespace
。

Namespace(命名空間)的特色在於,它在一條實際的連線(connection)上劃分出多個邏輯上的「區域」,每個區域都有自己的狀態和事件邏輯。也就是說,用相同的基礎連線,提供了多個功能區域的服務。
io.of("/orders").on("connection", (socket) => {
socket.on("order:list", () => {});
socket.on("order:create", () => {});
});
io.of("/users").on("connection", (socket) => {
socket.on("user:list", () => {});
});
程式碼說明:
1.io.of("/orders")
- 創建了一個名為
/orders
的命名空間,專門處理與「訂單」相關的事件。 - 當客戶端連接到
/orders
命名空間時,伺服器會監聽此命名空間內的特定事件。
事件監聽:
socket.on("order:list", () => {}
:
用來處理客戶端發送的 "order:list"
事件,比如請求獲取訂單列表。
socket.on("order:create", () => {})
:
用來處理客戶端發送的 "order:create"
事件,比如請求創建新訂單。
2.ioof("/users")
:
- 創建了一個名為
/users
的命名空間,專門處理與「使用者」相關的事件。 - 當客戶端連接到
/users
命名空間時,伺服器會監聽此命名空間內的特定事件。
事件監聽:
socket.on("user:list", () => {});
:
- 用來處理客戶端發送的
"user:list"
事件,比如請求獲取使用者列表。
3.執行流程:
- 當客戶端連接到不同命名空間時,它們的通訊是彼此獨立的。
例如: - 連接到 /orders 的客戶端,會與伺服器的 /orders 命名空間互動。
- 連接到 /users 的客戶端,則會與伺服器的 /users 命名空間互動。
※ Redis Support:透過 Redis 實現分佈式架構。
這張圖解釋了如何使用 Redis 支援分佈式架構,讓多個伺服器能共享資料並協同運作,適合用於大型分散式應用系統。

分佈式架構概念:
同樣一個服務透過多台伺服器共同分擔不同用戶,每台伺服器專注處理部分用戶或任務,並且透過一個中心化的資料庫或工具(如 Redis)來同步狀態和共享資訊。Redis 在這種架構中扮演的角色就是協調多台伺服器,確保它們之間的資料一致,讓多台伺服器看起來像是一台整體的服務。
※ Ack:用 WebSocket 實作傳統的 Request + Response。
- Ack(Acknowledgement) 的功能主要就是在 Socket.io 中實現一來一往的請求回應,類似於傳統的 Request-Response 模式。
- 當客戶端發送請求時,它可以提供一個回呼函數,伺服器處理完請求後呼叫該函數,將結果回傳給客戶端。
- 這種設計將回應和請求結合在一起,使 WebSocket 能支持類似 HTTP Request-Response 的模式,是一種高效的即時通訊方式。
//伺服器端
io.on("connection", (socket) => {
socket.on("update item", (arg1, arg2, callback) => {
console.log(arg1); // 1
console.log(arg2); // { name: "updated" }
callback({
status: "ok"
});
});
});
程式碼說明:
socket.on("update item", ...)
:監聽客戶端發送的"update item"
事件。callback
:接收來自客戶端的回呼函數,執行操作後,將結果(如{ status: "ok" }
)回傳。
//客戶端
socket.emit("update item", "1", { name: "updated" }, (response) => {
console.log(response.status); // 輸出:ok
});
程式碼說明:
socket.emit("update item", ...)
:向伺服器發送"update item"
事件,並附帶數據(如"1"
和{ name: "updated" }
)。- 最後的回呼函數
(response) => {}
:負責處理伺服器回傳的結果(如{ status: "ok" }
)。
※ Auto Reconnect:斷線自動重新連結。
當前端與伺服器的連線因任何原因中斷時,它會嘗試自動重新建立連線。
※ Fallback transport:替代傳輸方案。
當Socket無法連線時,Socket.io它會自動切換為long pulling做為替代傳輸方案,但使用和開發上是完全一樣。
※ Volatile Events:類似 UDP 的不可靠傳輸。
傳輸層的網路有兩種:
- 一種是TCP通信(可靠傳輸):每次請求必須得到回應,確認對方已成功接收,像是 HTTP 和 WebSocket。
- 另一種是UDP通信(不可靠傳輸):UDP特性就是發送請求後不確認對方是否收到,直接持續傳輸資料。應用場景:遊戲中快速的狀態更新或直播畫面刷新。
Volatile Events(不可靠事件)的特性:
它的傳輸方式與 UDP(User Datagram Protocol) 類似,是一種不可靠的傳輸模式。在這種模式中,當發送事件時,不會保證對方成功接收,且事件也不會被重試或緩存。
//伺服器端
io.on("connection", (socket) => {
console.log("connect");
socket.on("ping", (count) => {
console.log(count);
});
});
程式碼說明:
- io.on("connection", (socket) => { ... })
- io.on("connection", ...) 是 Socket.io 的伺服器端方法,用於監聽新的客戶端連線。
- 每當有新的客戶端連線到伺服器時,伺服器會執行一次 console.log("connect"),在伺服器端輸出文字 connect,表明連線成功。
- 連線建立後,會為該客戶端創建一個 socket 物件,用於客戶端和伺服器之間的通訊。
- socket.on("ping", (count) => { ... })
- socket.on 是用來監聽特定事件的方法。
- 在這裡,伺服器監聽名為 ping 的事件,並接收客戶端發送過來的數據(count)。
- 每次伺服器收到 ping 事件時,會執行 console.log(count),將事件攜帶的資料輸出到伺服器的控制台。
程式碼運作流程:
- 客戶端連線到伺服器時,觸發
connection
事件,伺服器輸出connect
。 - 客戶端可以透過
ping
事件向伺服器發送數據(例如計數器count
)。 - 伺服器接收
ping
事件,並輸出事件攜帶的count
數值。
伺服器輸出範例(第一種情況):
connect
1
2
3
4
# 伺服器重新啟動,客戶端自動重新連線並發送緩存的事件
connect
5
6
7
8
9
10
11
//客戶端:
let count = 0;
setInterval(() => {
socket.volatile.emit("ping", ++count);
}, 1000);
程式碼說明:
- let count = 0;
- 定義了一個計數器 count,用於追蹤事件的次數。
- setInterval(() => { ... }, 1000)
- 每隔 1 秒執行一次。
- 每次執行時,計數器 count 加 1,並透過 socket.volatile.emit 發送 ping 事件。
- socket.volatile.emit("ping", ++count)
- 使用 volatile.emit 發送事件。這是一個不可靠的傳輸模式,如果伺服器當時無法接收該事件,它不會嘗試重傳,也不會緩存事件。
伺服器輸出範例(第二種情況):
connect
1
2
3
4
# 伺服器重新啟動,客戶端自動重新連線
connect
5
6
7
8
9
10
11