簡介
如果您是 Socket.IO 新手,我們建議您查看我們的 教學。
什麼是 Socket.IO
Socket.IO 是一個能讓客戶端與伺服器之間進行低延遲、雙向且基於事件通訊的函式庫。


Socket.IO 連線可以使用不同的低階傳輸方式建立
- HTTP 長輪詢
- WebSocket
- WebTransport
Socket.IO 會自動選擇最適合的選項,取決於
您可以在 "運作原理" 區段 中找到更多詳細資訊。
伺服器實作
語言 | 網站 |
---|---|
JavaScript (Node.js) | - 安裝步驟 - API - 原始碼 |
JavaScript (Deno) | https://github.com/socketio/socket.io-deno |
Java | https://github.com/mrniko/netty-socketio |
Java | https://github.com/trinopoty/socket.io-server-java |
Python | https://github.com/miguelgrinberg/python-socketio |
Golang | https://github.com/googollee/go-socket.io |
Rust | https://github.com/Totodore/socketioxide |
客戶端實作
Socket.IO 不是什麼
Socket.IO 不是 WebSocket 實作。
儘管 Socket.IO 確實會在可能的情況下使用 WebSocket 作為傳輸,但它會在每個封包中新增額外的元資料。這就是為什麼 WebSocket 客戶端無法成功連線到 Socket.IO 伺服器,而 Socket.IO 客戶端也無法連線到一般 WebSocket 伺服器的原因。
// WARNING: the client will NOT be able to connect!
const socket = io("ws://echo.websocket.org");
如果您正在尋找一般 WebSocket 伺服器,請查看 ws 或 µWebSockets.js。
也有 討論將 WebSocket 伺服器納入 Node.js 核心。
在客戶端方面,您可能會對 robust-websocket 套件有興趣。
Socket.IO 不適用於行動應用程式的背景服務。
Socket.IO 函式庫會與伺服器保持開啟的 TCP 連線,這可能會導致使用者電池電量大量消耗。請針對此使用案例使用專用的訊息傳遞平台,例如 FCM。
功能
以下是 Socket.IO 在一般 WebSockets 上提供的功能
HTTP 長輪詢備援
如果無法建立 WebSocket 連線,連線將會備援到 HTTP 長輪詢。
此功能是十多年前建立此專案時,人們使用 Socket.IO 的首要原因,因為當時瀏覽器對 WebSockets 的支援仍處於起步階段。
即使現在大多數瀏覽器都支援 WebSockets(超過 97%),這仍然是一項很棒的功能,因為我們仍會收到使用者回報,表示他們無法建立 WebSocket 連線,因為他們位於設定錯誤的代理伺服器之後。
自動重新連線
在某些特定條件下,伺服器和客戶端之間的 WebSocket 連線可能會中斷,而雙方都不知道連結已中斷。
這就是為什麼 Socket.IO 包含心跳機制,會定期檢查連線狀態。
當用戶端最後斷線時,它會自動以指數退避延遲重新連線,以避免壓垮伺服器。
封包緩衝
當用戶端斷線時,封包會自動緩衝,並在重新連線時傳送。
更多資訊 在此。
確認
Socket.IO 提供一種便利的方式來傳送事件並接收回應
傳送方
socket.emit("hello", "world", (response) => {
console.log(response); // "got it"
});
接收方
socket.on("hello", (arg, callback) => {
console.log(arg); // "world"
callback("got it");
});
您也可以新增逾時
socket.timeout(5000).emit("hello", "world", (err, response) => {
if (err) {
// the other side did not acknowledge the event in the given delay
} else {
console.log(response); // "got it"
}
});
廣播
在伺服器端,您可以將事件傳送給 所有連線的用戶端 或 部分用戶端
// to all connected clients
io.emit("hello");
// to all connected clients in the "news" room
io.to("news").emit("hello");
這在 擴充到多個節點 時也能運作。
多工
命名空間讓您可以在單一共享連線中分割應用程式的邏輯。例如,如果您想要建立一個只有授權使用者才能加入的「管理員」頻道,這會很有用。
io.on("connection", (socket) => {
// classic users
});
io.of("/admin").on("connection", (socket) => {
// admin users
});
更多資訊 在此。
常見問題
Socket.IO 在今天仍然需要嗎?
這是一個公平的問題,因為現在 幾乎所有地方 都支援 WebSocket。
話雖如此,我們相信,如果您為應用程式使用純粹的 WebSocket,最終您將需要實作 Socket.IO 中已包含(且經過實戰測試)的大部分功能,例如 重新連線、確認 或 廣播。
Socket.IO 協定的開銷是什麼?
socket.emit("hello", "world")
將會傳送為單一的 WebSocket 框架,包含 42["hello","world"]
,其中
4
為 Engine.IO「訊息」封包類型2
為 Socket.IO「訊息」封包類型["hello","world"]
為參數陣列的JSON.stringify()
版本
因此,每個訊息會多出幾個位元組,而這些位元組可以使用 自訂剖析器 進一步減少。
瀏覽器套件本身的大小為 10.4 kB
(已縮小和壓縮)。
您可以在 這裡 找到 Socket.IO 協定的詳細資訊。
有些東西沒有正常運作,請協助?
請查看我們的 疑難排解指南。