客户端选项
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 事件

此行为特定于 Firefox,在其他浏览器中,当用户重新加载页面时,Socket 实例不会发出任何 disconnect 事件。
当此选项设置为 true 时,所有浏览器都将具有相同的行为(重新加载页面时不会发出 disconnect 事件)

如果您在应用程序中使用 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 中起作用。
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"
});
参考
- https://datatracker.ietf.org/doc/html/rfc6455#section-1.9
- https://mdn.org.cn/en-US/docs/Web/API/WebSocket/WebSocket
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 长轮询:连续的 HTTP 请求(POST用于写入,GET用于读取)
- WebSocket
- WebTransport
以下示例禁用 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.0 | Node.js 客户端现在尊重 withCredentials设置。 | 
| v3.0.0 | withCredentials现在默认为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 独有的选项,它不会绕过浏览器中的安全检查

管理器选项
这些设置将由附加到相同 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) => { /* ... */ });