即時通訊 — Socket.io

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

※ 什麼是 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 ] }
});

程式碼說明:

伺服器向客戶端發送事件時,可以傳遞多個參數,包括數字、字串和物件。客戶端正確地接收並打印了這些參數的值。

raw-image

※ Rooms:分組通信

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

※ Namespace:命名空間

架構圖解:

  • Client 部分包含兩個框:Default namespaceAdmin namespace
  • 中間是 one single pipe,代表客戶端與伺服器之間的一個連線。
  • Server 部分同樣包含兩個框:Default namespaceAdmin namespace
raw-image

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 支援分佈式架構,讓多個伺服器能共享資料並協同運作,適合用於大型分散式應用系統。

raw-image

分佈式架構概念:

同樣一個服務透過多台伺服器共同分擔不同用戶,每台伺服器專注處理部分用戶或任務,並且透過一個中心化的資料庫或工具(如 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);
});
});

程式碼說明:

  1. io.on("connection", (socket) => { ... })
    • io.on("connection", ...) 是 Socket.io 的伺服器端方法,用於監聽新的客戶端連線。
    • 每當有新的客戶端連線到伺服器時,伺服器會執行一次 console.log("connect"),在伺服器端輸出文字 connect,表明連線成功。
    • 連線建立後,會為該客戶端創建一個 socket 物件,用於客戶端和伺服器之間的通訊。
  2. socket.on("ping", (count) => { ... })
    • socket.on 是用來監聽特定事件的方法。
    • 在這裡,伺服器監聽名為 ping 的事件,並接收客戶端發送過來的數據(count)。
    • 每次伺服器收到 ping 事件時,會執行 console.log(count),將事件攜帶的資料輸出到伺服器的控制台。

程式碼運作流程

  1. 客戶端連線到伺服器時,觸發 connection 事件,伺服器輸出 connect
  2. 客戶端可以透過 ping 事件向伺服器發送數據(例如計數器 count)。
  3. 伺服器接收 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);

程式碼說明:

  1. let count = 0;
    • 定義了一個計數器 count,用於追蹤事件的次數。
  2. setInterval(() => { ... }, 1000)
    • 每隔 1 秒執行一次。
    • 每次執行時,計數器 count 加 1,並透過 socket.volatile.emit 發送 ping 事件。
  3. socket.volatile.emit("ping", ++count)
    • 使用 volatile.emit 發送事件。這是一個不可靠的傳輸模式,如果伺服器當時無法接收該事件,它不會嘗試重傳,也不會緩存事件。

伺服器輸出範例(第二種情況):

connect  
1
2
3
4
# 伺服器重新啟動,客戶端自動重新連線
connect
5
6
7
8
9
10
11


留言
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/06
※ 建立靜態的網頁腳本: <!DOCTYPE html> <html> <head>   <title>WebSocket minimal demo</title> </head> <body>   <!-- 聊天室紀錄 -->   <ul class="chat-list"></ul>   <!
Thumbnail
2025/04/06
※ 建立靜態的網頁腳本: <!DOCTYPE html> <html> <head>   <title>WebSocket minimal demo</title> </head> <body>   <!-- 聊天室紀錄 -->   <ul class="chat-list"></ul>   <!
Thumbnail
看更多
你可能也想看
Thumbnail
每年4月、5月都是最多稅要繳的月份,當然大部份的人都是有機會繳到「綜合所得稅」,只是相當相當多人還不知道,原來繳給政府的稅!可以透過一些有活動的銀行信用卡或電子支付來繳,從繳費中賺一點點小確幸!就是賺個1%~2%大家也是很開心的,因為你們把沒回饋變成有回饋,就是用卡的最高境界 所得稅線上申報
Thumbnail
每年4月、5月都是最多稅要繳的月份,當然大部份的人都是有機會繳到「綜合所得稅」,只是相當相當多人還不知道,原來繳給政府的稅!可以透過一些有活動的銀行信用卡或電子支付來繳,從繳費中賺一點點小確幸!就是賺個1%~2%大家也是很開心的,因為你們把沒回饋變成有回饋,就是用卡的最高境界 所得稅線上申報
Thumbnail
全球科技產業的焦點,AKA 全村的希望 NVIDIA,於五月底正式發布了他們在今年 2025 第一季的財報 (輝達內部財務年度為 2026 Q1,實際日曆期間為今年二到四月),交出了打敗了市場預期的成績單。然而,在銷售持續高速成長的同時,川普政府加大對於中國的晶片管制......
Thumbnail
全球科技產業的焦點,AKA 全村的希望 NVIDIA,於五月底正式發布了他們在今年 2025 第一季的財報 (輝達內部財務年度為 2026 Q1,實際日曆期間為今年二到四月),交出了打敗了市場預期的成績單。然而,在銷售持續高速成長的同時,川普政府加大對於中國的晶片管制......
Thumbnail
重點摘要: 6 月繼續維持基準利率不變,強調維持高利率主因為關稅 點陣圖表現略為鷹派,收斂 2026、2027 年降息預期 SEP 連續 2 季下修 GDP、上修通膨預測值 --- 1.繼續維持利率不變,強調需要維持高利率是因為關稅: 聯準會 (Fed) 召開 6 月利率會議
Thumbnail
重點摘要: 6 月繼續維持基準利率不變,強調維持高利率主因為關稅 點陣圖表現略為鷹派,收斂 2026、2027 年降息預期 SEP 連續 2 季下修 GDP、上修通膨預測值 --- 1.繼續維持利率不變,強調需要維持高利率是因為關稅: 聯準會 (Fed) 召開 6 月利率會議
Thumbnail
這篇文章介紹了網站的整體架構以及開發時所使用的工具和套件,包括 Next.js、Tailwind CSS 和 socket.io 等。文章回顧了程式碼的重構與優化,幫助開發者提高工作效率,適合希望深入瞭解前端開發和網站架構的讀者。
Thumbnail
這篇文章介紹了網站的整體架構以及開發時所使用的工具和套件,包括 Next.js、Tailwind CSS 和 socket.io 等。文章回顧了程式碼的重構與優化,幫助開發者提高工作效率,適合希望深入瞭解前端開發和網站架構的讀者。
Thumbnail
一、什麼是WinSocket? 也就是大家常說的WinSock全名為Windows Sockets API (WSA),它會透過TCP/IP通訊協定來做網路的通訊,會用在Windows操作系統上來開發網路應用的API(應用程式介面)   二、WinSocket用在哪裡?   Socket可以
Thumbnail
一、什麼是WinSocket? 也就是大家常說的WinSock全名為Windows Sockets API (WSA),它會透過TCP/IP通訊協定來做網路的通訊,會用在Windows操作系統上來開發網路應用的API(應用程式介面)   二、WinSocket用在哪裡?   Socket可以
Thumbnail
※ 什麼是Web API API 就是後端開出來讓前端來用的介面,讓前端與後端可以溝通。 API流程: 終端使用者用任何一種裝置進入瀏覽器。 瀏覽器透過 API 向後端發出請求,請求查詢或修改資料。 後端透過 API 收到前端的請求後,取得資料並回應給前端。 前端渲染畫面,終端使用者
Thumbnail
※ 什麼是Web API API 就是後端開出來讓前端來用的介面,讓前端與後端可以溝通。 API流程: 終端使用者用任何一種裝置進入瀏覽器。 瀏覽器透過 API 向後端發出請求,請求查詢或修改資料。 後端透過 API 收到前端的請求後,取得資料並回應給前端。 前端渲染畫面,終端使用者
Thumbnail
訊息的即時傳遞已然成為現代社會的趨勢了, 而扮演中樞平台的系統架構功能也漸趨複雜完整, Kafka是一個事件流平台, 正好滿足串流時代之下的即時訊息傳遞架構, 因此我們有必要深入來學習這套事件流平台, 不論是自動化、金融交易、IOT、物流…皆離不開即時的需求, 所以就讓我們蹲好馬步來好好的學習一
Thumbnail
訊息的即時傳遞已然成為現代社會的趨勢了, 而扮演中樞平台的系統架構功能也漸趨複雜完整, Kafka是一個事件流平台, 正好滿足串流時代之下的即時訊息傳遞架構, 因此我們有必要深入來學習這套事件流平台, 不論是自動化、金融交易、IOT、物流…皆離不開即時的需求, 所以就讓我們蹲好馬步來好好的學習一
Thumbnail
前段時間我們有介紹「【Python 軍火庫🧨 - websockets】雙向溝通的渠道」, 這種方式可以達到基本的連線沒問題,但隨著資安意識的抬頭, 我們的websocket連線也會需要在通道之上進行加密, 那麼我們將根據使用情境來教您如何選用適當的連線。 Server端 我們的Serve
Thumbnail
前段時間我們有介紹「【Python 軍火庫🧨 - websockets】雙向溝通的渠道」, 這種方式可以達到基本的連線沒問題,但隨著資安意識的抬頭, 我們的websocket連線也會需要在通道之上進行加密, 那麼我們將根據使用情境來教您如何選用適當的連線。 Server端 我們的Serve
Thumbnail
我們在 【Python 軍火庫🧨 - websockets】傳送/接收音檔並轉換成numpy(基礎篇) 有聊到要如何透過Websocket來傳送音檔,但上一篇的作法是在Client端就進行音訊的解碼動作,這樣會有一個缺點,假設Client的機器運算效能較差,那麼運算的結果勢必會較慢出現,對於使用者
Thumbnail
我們在 【Python 軍火庫🧨 - websockets】傳送/接收音檔並轉換成numpy(基礎篇) 有聊到要如何透過Websocket來傳送音檔,但上一篇的作法是在Client端就進行音訊的解碼動作,這樣會有一個缺點,假設Client的機器運算效能較差,那麼運算的結果勢必會較慢出現,對於使用者
Thumbnail
關於Websockets的篇章, 有興趣的朋友歡迎參考: 【Python 軍火庫 - websockets】雙向溝通的渠道 【Python 軍火庫 - websockets】用json來溝通吧! 而這一篇章的主題主要是來分享如何透過websockets傳遞音檔並進行解碼, 我們都知道聲
Thumbnail
關於Websockets的篇章, 有興趣的朋友歡迎參考: 【Python 軍火庫 - websockets】雙向溝通的渠道 【Python 軍火庫 - websockets】用json來溝通吧! 而這一篇章的主題主要是來分享如何透過websockets傳遞音檔並進行解碼, 我們都知道聲
Thumbnail
Websocket是一種網路傳輸的協定,讓建立一次handshake的過程就可以相互傳遞資料,而非同步的過程能夠讓處理事情更有效率,這篇文章將帶你深入瞭解Websocket如何運作、以及其特點與優勢。
Thumbnail
Websocket是一種網路傳輸的協定,讓建立一次handshake的過程就可以相互傳遞資料,而非同步的過程能夠讓處理事情更有效率,這篇文章將帶你深入瞭解Websocket如何運作、以及其特點與優勢。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News