跳到主要內容
版本:4.x

連線狀態復原

連線狀態復原是一項功能,可讓您在暫時中斷連線後還原用戶端的狀態,包括任何遺漏的封包。

資訊

此功能已新增至 2023 年 2 月發布的版本 4.6.0

發布說明可在 此處 找到。

免責聲明

在實際情況下,Socket.IO 用戶端無論連線品質如何,都難免會遇到暫時中斷連線的情況。

此功能將有助於您應對此類中斷,但除非您想永遠儲存封包和工作階段 (將 maxDisconnectionDuration 設定為 Infinity),否則您無法確保復原一定會成功。

這就是為什麼你仍需要處理客戶端和伺服器狀態必須同步的情況。

用法

連線狀態復原必須由伺服器啟用

const io = new Server(httpServer, {
connectionStateRecovery: {
// the backup duration of the sessions and the packets
maxDisconnectionDuration: 2 * 60 * 1000,
// whether to skip middlewares upon successful recovery
skipMiddlewares: true,
}
});

在意外斷線(即未手動斷線,且使用 socket.disconnect())時,伺服器會儲存 socket 的 id、房間和 data 屬性。

然後在重新連線時,伺服器會嘗試復原客戶端的狀態。recovered 屬性表示此復原是否成功

伺服器

io.on("connection", (socket) => {
if (socket.recovered) {
// recovery was successful: socket.id, socket.rooms and socket.data were restored
} else {
// new or unrecoverable session
}
});

用戶端

socket.on("connect", () => {
if (socket.recovered) {
// any event missed during the disconnection period will be received now
} else {
// new or unrecoverable session
}
});

你可以強制關閉底層引擎來檢查復原是否運作

import { io } from "socket.io-client";

const socket = io({
reconnectionDelay: 10000, // defaults to 1000
reconnectionDelayMax: 10000 // defaults to 5000
});

socket.on("connect", () => {
console.log("recovered?", socket.recovered);

setTimeout(() => {
if (socket.io.engine) {
// close the low-level connection and trigger a reconnection
socket.io.engine.close();
}
}, 10000);
});
提示

你也可以直接在瀏覽器中執行此範例,網址為

與現有轉接器的相容性

轉接器支援?
內建轉接器(記憶體中)是 ✅
Redis 轉接器1
Redis Streams 轉接器是 ✅
MongoDB 轉接器是 ✅(自版本 0.3.0 起)
Postgres 轉接器進行中
叢集轉接器進行中

[1] 持久化封包與 Redis PUB/SUB 機制不相容。

幕後運作方式

範例

40{"sid":"GNpWD7LbGCBNCr8GAAAB","pid":"YHcX2sdAF1z452-HAAAW"}

where

4 => the Engine.IO message type
0 => the Socket.IO CONNECT type
GN...AB => the public id of the session
YH...AW => the private id of the session
  • 伺服器也會在 每個封包 中包含一個偏移量(為了向後相容,會新增在資料陣列的結尾)

範例

42["foo","MzUPkW0"]

where

4 => the Engine.IO message type
2 => the Socket.IO EVENT type
foo => the event name (socket.emit("foo"))
MzUPkW0 => the offset
注意

為了讓復原成功,伺服器必須傳送至少一個事件,以便初始化客戶端端的偏移量。

  • 在暫時斷線時,伺服器會將用戶端狀態儲存在給定的延遲時間(在轉接器層級實作)

  • 在重新連線時,用戶端會同時傳送階段 ID 和它處理過的最後偏移量,而伺服器會嘗試還原狀態

範例

40{"pid":"YHcX2sdAF1z452-HAAAW","offset":"MzUPkW0"}

where

4 => the Engine.IO message type
0 => the Socket.IO CONNECT type
YH...AW => the private id of the session
MzUPkW0 => the last processed offset