跳至主要内容
版本: 4.x

客户端选项

IO 工厂选项

forceNew

默认值: false

是否创建一个新的 Manager 实例。

Manager 实例负责与服务器的低级连接(通过 HTTP 长轮询或 WebSocket 建立)。它处理重新连接逻辑。

Socket 实例是用于向服务器发送事件和接收服务器事件的接口。它属于给定的 命名空间

单个 Manager 可以附加到多个 Socket 实例。

以下示例将对 3 个 Socket 实例(单个 WebSocket 连接)重用相同的 Manager 实例

const socket = io("https://example.com"); // the main namespace
const productSocket = io("https://example.com/product"); // the "product" namespace
const orderSocket = io("https://example.com/order"); // the "order" namespace

以下示例将创建 3 个不同的 Manager 实例(因此 3 个不同的 WebSocket 连接)

const socket = io("https://example.com"); // the main namespace
const productSocket = io("https://example.com/product", { forceNew: true }); // the "product" namespace
const orderSocket = io("https://example.com/order", { forceNew: true }); // the "order" namespace

重用现有命名空间也会每次创建一个新的 Manager

const socket1 = io(); // 1st manager
const socket2 = io(); // 2nd manager
const socket3 = io("/admin"); // reuse the 1st manager
const socket4 = io("/admin"); // 3rd manager

multiplex

默认值: true

forceNew 的反面:是否重用现有的 Manager 实例。

const socket = io(); // 1st manager
const adminSocket = io("/admin", { multiplex: false }); // 2nd manager

低级引擎选项

信息

这些设置将由附加到相同 Manager 的所有 Socket 实例共享。

addTrailingSlash

在 v4.6.0 中添加

现在可以禁用默认添加的尾部斜杠

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

const socket = io("https://example.com", {
addTrailingSlash: false
});

在上面的示例中,请求 URL 将是 https://example.com/socket.io 而不是 https://example.com/socket.io/

autoUnref

在 v4.0.0 中添加

默认值: false

如果 autoUnref 设置为 true,Socket.IO 客户端将允许程序退出,即使客户端已连接,只要事件系统中没有其他活动的计时器/TCP 套接字。

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

const socket = io({
autoUnref: true
});

另请参阅:https://node.org.cn/api/timers.html#timeoutunref

closeOnBeforeunload

历史
版本更改
v4.7.1该选项现在默认为 false
v4.1.0首次实现。

默认值: false

是否在浏览器中发出 beforeunload 事件时(静默地)关闭连接。

当此选项设置为 false(默认值)时,当用户在 **Firefox** 上重新加载页面时,Socket 实例将发出 disconnect 事件

Example with Firefox when closeOnBeforeunload is set to false

注意

此行为特定于 Firefox,在其他浏览器中,当用户重新加载页面时,Socket 实例不会发出任何 disconnect 事件。

当此选项设置为 true 时,所有浏览器都将具有相同的行为(重新加载页面时不会发出 disconnect 事件)

Example with Firefox when closeOnBeforeunload is set to true

警告

如果您在应用程序中使用 beforeunload 事件(“您确定要离开此页面吗?”),建议将此选项保留为 false

有关更多信息,请查看 此问题

extraHeaders

默认值: -

附加的标头(然后在服务器端的 socket.handshake.headers 对象中找到)。

示例

客户端

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

const socket = io({
extraHeaders: {
"my-custom-header": "1234"
}
});

服务器

io.on("connection", (socket) => {
console.log(socket.handshake.headers); // an object containing "my-custom-header": "1234"
});
警告

在浏览器环境中,如果您只启用 WebSocket 传输,则 extraHeaders 选项将被忽略,因为浏览器中的 WebSocket API 不允许提供自定义标头。

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

const socket = io({
transports: ["websocket"],
extraHeaders: {
"my-custom-header": "1234" // ignored
}
});

但这将在 Node.js 或 React-Native 中起作用。

文档:WebSocket API

forceBase64

默认值: false

是否强制对通过 WebSocket 发送的二进制内容进行 Base64 编码(始终对 HTTP 长轮询启用)。

path

默认值: /socket.io/

它是服务器端捕获的路径的名称。

警告

服务器和客户端的值必须匹配(除非您在两者之间使用路径重写代理)。

客户端

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

const socket = io("https://example.com", {
path: "/my-custom-path/"
});

服务器

import { createServer } from "http";
import { Server } from "socket.io";

const httpServer = createServer();
const io = new Server(httpServer, {
path: "/my-custom-path/"
});

请注意,这与 URI 中的路径不同,URI 中的路径表示 命名空间

示例

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

const socket = io("https://example.com/order", {
path: "/my-custom-path/"
});
  • Socket 实例附加到“order”命名空间
  • HTTP 请求将类似于:GET https://example.com/my-custom-path/?EIO=4&transport=polling&t=ML4jUwU

protocols

在 v2.0.0 中添加

默认值: -

单个协议字符串或协议字符串数组。这些字符串用于指示子协议,以便单个服务器可以实现多个 WebSocket 子协议(例如,您可能希望一个服务器能够根据指定的协议处理不同类型的交互)。

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

const socket = io({
transports: ["websocket"],
protocols: ["my-protocol-v1"]
});

服务器

io.on("connection", (socket) => {
const transport = socket.conn.transport;
console.log(transport.socket.protocol); // prints "my-protocol-v1"
});

参考

query

默认值: -

附加的查询参数(然后在服务器端的 socket.handshake.query 对象中找到)。

示例

客户端

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

const socket = io({
query: {
x: 42
}
});

服务器

io.on("connection", (socket) => {
console.log(socket.handshake.query); // prints { x: "42", EIO: "4", transport: "polling" }
});

查询参数在会话期间无法更新,因此在客户端更改 query 仅在当前会话关闭并创建新会话时有效

socket.io.on("reconnect_attempt", () => {
socket.io.opts.query.x++;
});

注意:以下查询参数是保留的,不能在您的应用程序中使用

  • EIO:协议版本(当前为“4”)
  • transport:传输名称(“polling”或“websocket”)
  • sid:会话 ID
  • j:如果传输是轮询,但需要 JSONP 响应
  • t:用于缓存清除的哈希时间戳

rememberUpgrade

默认值: false

如果为 true 并且先前到服务器的 WebSocket 连接成功,连接尝试将绕过正常的升级过程,并将首先尝试 WebSocket。在传输错误之后的连接尝试将使用正常的升级过程。建议您仅在使用 SSL/TLS 连接时或在您知道您的网络不会阻止 websocket 时启用此选项。

timestampParam

默认值: "t"

用作时间戳键的查询参数的名称。

timestampRequests

默认值: true

是否将时间戳查询参数添加到每个请求(用于缓存清除)。

transportOptions

在 v2.0.0 中添加

默认值: {}

特定于传输的选项。

示例

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

const socket = io({
path: "/path-for-http-long-polling/",
transportOptions: {
websocket: {
path: "/path-for-websocket/"
}
}
});

transports

历史
版本更改
v4.7.0添加了 webtransport
v1.0.0首次实现。

默认值: ["polling", "websocket", "webtransport"]

与 Socket.IO 服务器的低级连接可以通过以下方式建立

以下示例禁用 HTTP 长轮询传输

const socket = io("https://example.com", { transports: ["websocket"] });

注意:在这种情况下,服务器端不需要粘性会话(更多信息 此处)。

默认情况下,HTTP 长轮询连接首先建立,然后尝试升级到 WebSocket(解释 此处)。您可以使用 WebSocket 优先

const socket = io("https://example.com", {
transports: ["websocket", "polling"] // use WebSocket first, if available
});

socket.on("connect_error", () => {
// revert to classic upgrade
socket.io.opts.transports = ["polling", "websocket"];
});

一个可能的缺点是,只有在 WebSocket 连接无法建立时才会检查 CORS 配置 的有效性。

upgrade

默认值: true

客户端是否应该尝试将传输从 HTTP 长轮询升级到更好的东西。

withCredentials

历史
版本更改
v4.7.0Node.js 客户端现在尊重 withCredentials 设置。
v3.0.0withCredentials 现在默认为 false
v1.0.0首次实现。

默认值: false

跨站点请求是否应包含凭据,例如 cookie、授权标头或 TLS 客户端证书。设置 withCredentials 对同站点请求没有影响。

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

const socket = io("https://my-backend.com", {
withCredentials: true
});

服务器需要发送正确的 Access-Control-Allow-* 标头以允许连接

import { createServer } from "http";
import { Server } from "socket.io";

const httpServer = createServer();
const io = new Server(httpServer, {
cors: {
origin: "https://my-frontend.com",
credentials: true
}
});
警告

当将 withCredentials 设置为 true 时,您不能使用 origin: *。这将触发以下错误

跨源请求被阻止:同源策略不允许读取位于‘.../socket.io/?EIO=4&transport=polling&t=NvQfU77’ 的远程资源。(原因:如果 CORS 标头‘Access-Control-Allow-Origin’ 为‘*’,则不支持凭据)

文档

信息

从版本 4.7.0 开始,当将 withCredentials 选项设置为 true 时,Node.js 客户端现在将在 HTTP 请求中包含 cookie,使其更易于与基于 cookie 的粘性会话一起使用。

特定于 Node.js 的选项

支持以下选项

  • agent
  • pfx
  • key
  • passphrase
  • cert
  • ca
  • 密码
  • rejectUnauthorized

请参考 Node.js 文档

自签名证书示例

客户端

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

const socket = io("https://example.com", {
ca: readFileSync("./cert.pem")
});

服务器

import { readFileSync } from "fs";
import { createServer } from "https";
import { Server } from "socket.io";

const httpServer = createServer({
cert: readFileSync("./cert.pem"),
key: readFileSync("./key.pem")
});
const io = new Server(httpServer);

客户端证书身份验证示例

客户端

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

const socket = io("https://example.com", {
ca: readFileSync("./server-cert.pem"),
cert: readFileSync("./client-cert.pem"),
key: readFileSync("./client-key.pem"),
});

服务器

import { readFileSync } from "fs";
import { createServer } from "https";
import { Server } from "socket.io";

const httpServer = createServer({
cert: readFileSync("./server-cert.pem"),
key: readFileSync("./server-key.pem"),
requestCert: true,
ca: [
readFileSync("client-cert.pem")
]
});
const io = new Server(httpServer);
警告

rejectUnauthorized 是 Node.js 独有的选项,它不会绕过浏览器中的安全检查

Security warning in the browser

管理器选项

信息

这些设置将由附加到相同 Manager 的所有 Socket 实例共享。

autoConnect

默认值: true

是否在创建时自动连接。如果设置为 false,则需要手动连接

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

const socket = io({
autoConnect: false
});

socket.connect();
// or
socket.io.open();

parser

在 v2.2.0 中添加

默认值:require("socket.io-parser")

用于编组/解组数据包的解析器。有关更多信息,请参见 此处

randomizationFactor

默认值:0.5

重新连接时使用的随机化因子(例如,这样客户端就不会在服务器崩溃后完全在同一时间重新连接)。

使用默认值的示例

  • 第一次重新连接尝试发生在 500 到 1500 毫秒之间 (1000 * 2^0 * (<介于 -0.5 和 1.5 之间的某个值>))
  • 第二次重新连接尝试发生在 1000 到 3000 毫秒之间 (1000 * 2^1 * (<介于 -0.5 和 1.5 之间的某个值>))
  • 第三次重新连接尝试发生在 2000 到 5000 毫秒之间 (1000 * 2^2 * (<介于 -0.5 和 1.5 之间的某个值>))
  • 接下来的重新连接尝试将在 5000 毫秒后发生

reconnection

默认值: true

是否启用重新连接。如果设置为 false,则需要手动重新连接

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

const socket = io({
reconnection: false
});

const tryReconnect = () => {
setTimeout(() => {
socket.io.open((err) => {
if (err) {
tryReconnect();
}
});
}, 2000);
}

socket.io.on("close", tryReconnect);

reconnectionAttempts

默认值:Infinity

放弃之前重新连接尝试的次数。

reconnectionDelay

默认值:1000

重新连接之前的初始延迟(以毫秒为单位)(受 randomizationFactor 值的影响)。

reconnectionDelayMax

默认值:5000

两次重新连接尝试之间的最大延迟。每次尝试都会将重新连接延迟增加 2 倍。

timeout

默认值:20000

每次连接尝试的超时时间(以毫秒为单位)。

套接字选项

信息

这些设置特定于给定的套接字实例。

ackTimeout

在 v4.6.0 中添加

默认值: -

等待确认时使用的默认超时时间(以毫秒为单位)(不要与现有的 timeout 选项混淆,该选项由管理器在连接期间使用)

auth

在 v3.0.0 中添加

默认值: -

访问命名空间时发送的凭据(另请参见 此处)。

示例

客户端

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

const socket = io({
auth: {
token: "abcd"
}
});

// or with a function
const socket = io({
auth: (cb) => {
cb({ token: localStorage.token })
}
});

服务器

io.on("connection", (socket) => {
console.log(socket.handshake.auth); // prints { token: "abcd" }
});

当拒绝访问命名空间时,您可以更新 auth 映射

socket.on("connect_error", (err) => {
if (err.message === "invalid credentials") {
socket.auth.token = "efgh";
socket.connect();
}
});

或手动强制套接字实例重新连接

socket.auth.token = "efgh";
socket.disconnect().connect();

retries

在 v4.6.0 中添加

默认值: -

最大重试次数。超过限制,数据包将被丢弃。

const socket = io({
retries: 3,
ackTimeout: 10000
});

// implicit ack
socket.emit("my-event");

// explicit ack
socket.emit("my-event", (err, val) => { /* ... */ });

// custom timeout (in that case the ackTimeout is optional)
socket.timeout(5000).emit("my-event", (err, val) => { /* ... */ });