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

服务器选项

Socket.IO 服务器选项

以下选项会影响 Socket.IO 服务器的行为。

adapter

默认值: require("socket.io-adapter") (内存适配器,其源代码可以在 这里 找到)

要使用的 "适配器"

使用 Redis 适配器 的示例

const { Server } = require("socket.io");
const { createAdapter } = require("@socket.io/redis-adapter");
const { createClient } = require("redis");

const pubClient = createClient({ host: "localhost", port: 6379 });
const subClient = pubClient.duplicate();

const io = new Server({
adapter: createAdapter(pubClient, subClient)
});

io.listen(3000);

cleanupEmptyChildNamespaces

在 v4.6.0 中添加

默认值: false

是否删除 子命名空间,这些命名空间没有连接到它们的套接字。

如果您创建了许多动态命名空间,此选项可能很有用,因为每个命名空间都会创建自己的适配器实例。

启用此选项(默认情况下禁用)后,当套接字从动态命名空间断开连接时,如果没有任何其他套接字连接到它,则该命名空间将被清理,并且它的适配器将被关闭。

connectionStateRecovery

在 v4.6.0 中添加

默认值: undefined

用于 连接状态恢复 功能的选项

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,
}
});

如果 skipMiddlewares 选项设置为 true,则在成功恢复连接时将跳过中间件

function computeUserIdFromHeaders(headers) {
// to be implemented
}

// this middleware will be skipped if the connection is successfully recovered
io.use(async (socket, next) => {
socket.data.userId = await computeUserIdFromHeaders(socket.handshake.headers);

next();
});

io.on("connection", (socket) => {
// the userId attribute will either come:
// - from the middleware above (first connection or failed recovery)
// - from the recevery mechanism
console.log("userId", socket.data.userId);
});

connectTimeout

默认值: 45000

在断开尚未成功加入命名空间的客户端连接之前的毫秒数。

parser

默认值: socket.io-parser

要使用的解析器。请参阅 此处 的文档。

path

默认值: /socket.io/

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

注意

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

服务器

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

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

客户端

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

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

serveClient

默认值: true

是否提供客户端文件。如果为 true,则不同的捆绑包将在以下位置提供

  • <url>/socket.io/socket.io.js
  • <url>/socket.io/socket.io.min.js
  • <url>/socket.io/socket.io.msgpack.min.js

(包括它们相关的源映射)

另请参阅 此处

底层引擎选项

以下选项会影响底层 Engine.IO 服务器的行为。

addTrailingSlash

在 v4.6.0 中添加

默认值: true

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

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

const httpServer = createServer();
const io = new Server(httpServer, {
addTrailingSlash: false
});

在上面的示例中,客户端可以省略尾部斜杠,并使用 /socket.io 而不是 /socket.io/

allowEIO3

默认值: false

是否启用与 Socket.IO v2 客户端的兼容性。

另请参阅:从 2.x 迁移到 3.0

示例

const io = new Server(httpServer, {
allowEIO3: true // false by default
});

allowRequest

默认值: -

一个函数,它接收给定的握手或升级请求作为其第一个参数,并且可以决定是否继续。

示例

const io = new Server(httpServer, {
allowRequest: (req, callback) => {
const isOriginValid = check(req);
callback(null, isOriginValid);
}
});

这也可以与 initial_headers 事件结合使用,向客户端发送 cookie

import { serialize } from "cookie";

const io = new Server(httpServer, {
allowRequest: async (req, callback) => {
const session = await fetchSession(req);
req.session = session;
callback(null, true);
}
});

io.engine.on("initial_headers", (headers, req) => {
if (req.session) {
headers["set-cookie"] = serialize("sid", req.session.id, { sameSite: "strict" });
}
});

另请参阅

allowUpgrades

默认值: true

是否允许传输升级。

默认值: -

将转发到 cookie 模块的选项列表。可用选项

  • 编码
  • 过期
  • httpOnly
  • maxAge
  • 路径
  • sameSite
  • 安全

示例

import { Server } from "socket.io";

const io = new Server(httpServer, {
cookie: {
name: "my-cookie",
httpOnly: true,
sameSite: "strict",
maxAge: 86400
}
});
信息

从 Socket.IO v3 开始,不再默认发送 cookie (参考)。

cors

默认值: -

将转发到 cors 模块的选项列表。更多信息可以在 此处 找到。

示例

  • 允许给定的来源
const io = new Server(httpServer, {
cors: {
origin: ["https://example.com"]
}
});
  • 允许给定的来源用于本地开发
const io = new Server(httpServer, {
cors: {
origin: process.env.NODE_ENV === "production" ? false : ["http://localhost:3000"]
}
});
  • 允许给定的来源、标头和凭据(例如 cookie、授权标头或 TLS 客户端证书)
const io = new Server(httpServer, {
cors: {
origin: ["https://example.com", "https://dev.example.com"],
allowedHeaders: ["my-custom-header"],
credentials: true
}
});
注意

如果您希望浏览器发送凭据(例如 cookie、授权标头或 TLS 客户端证书),您还需要在客户端设置 withCredentials 选项为 true

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

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

更多信息 此处

  • 允许任何来源
const io = new Server(httpServer, {
cors: {
origin: "*"
}
});
危险

请注意,在这种情况下,您实际上是在禁用跨源资源共享 (CORS) 提供的安全性,因为任何域都可以访问您的服务器。请谨慎使用。

可用选项

选项描述
来源配置 Access-Control-Allow-Origin CORS 标头。
方法配置 Access-Control-Allow-Methods CORS 标头。需要逗号分隔的字符串(例如:'GET,PUT,POST')或数组(例如:['GET', 'PUT', 'POST'])。
allowedHeaders配置 Access-Control-Allow-Headers CORS 标头。需要逗号分隔的字符串(例如:'Content-Type,Authorization')或数组(例如:['Content-Type', 'Authorization'])。如果未指定,则默认为反映请求的 Access-Control-Request-Headers 标头中指定的标头。
exposedHeaders配置 Access-Control-Expose-Headers CORS 标头。需要逗号分隔的字符串(例如:'Content-Range,X-Content-Range')或数组(例如:['Content-Range', 'X-Content-Range'])。如果未指定,则不会公开任何自定义标头。
凭据配置 Access-Control-Allow-Credentials CORS 标头。设置为 true 以传递标头,否则将省略。
maxAge配置 Access-Control-Max-Age CORS 标头。设置为整数以传递标头,否则将省略。
preflightContinue将 CORS 预检响应传递给下一个处理程序。
optionsSuccessStatus提供一个状态代码用于成功的 OPTIONS 请求,因为一些旧的浏览器(IE11、各种智能电视)无法处理 204

origin 选项的可能值

  • Boolean - 将 origin 设置为 true 以反映 请求来源,如 req.header('Origin') 所定义,或将其设置为 false 以禁用 CORS。
  • String - 将 origin 设置为特定来源。例如,如果您将其设置为 "http://example.com",则只允许来自 "http://example.com" 的请求。
  • RegExp - 将 origin 设置为将用于测试请求来源的正则表达式模式。如果匹配,则将反映请求来源。例如,模式 /example\.com$/ 将反映来自以“example.com”结尾的来源的任何请求。
  • Array - 将 origin 设置为有效来源的数组。每个来源可以是 StringRegExp。例如,["http://example1.com", /\.example2\.com$/] 将接受来自 "http://example1.com" 或来自“example2.com”的子域的任何请求。
  • Function - 将 origin 设置为实现某些自定义逻辑的函数。该函数将请求来源作为第一个参数,并将回调(它期望签名 err [object], allow [bool])作为第二个参数。
注意

即使有多个域,选项的名称也是 origin(而不是 origins

const io = new Server(httpServer, {
cors: {
// BAD
origins: ["https://example.com"],
// GOOD
origin: ["https://example.com"],
}
});
注意

在设置 credentials: true 时,您不能使用 origin: "*"

// THIS WON'T WORK
const io = new Server(httpServer, {
cors: {
origin: "*",
credentials: true
}
});

您将在浏览器控制台中看到类似这样的错误

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

您需要提供域列表(推荐解决方案)或使用以下方法

const io = new Server(httpServer, {
cors: {
origin: (_req, callback) => {
callback(null, true);
},
credentials: true
}
});

请注意,在这种情况下,与 origin: "*"origin: true 一样,您实际上是在禁用跨源资源共享 (CORS) 提供的安全性,因为任何域都可以访问您的服务器。请谨慎使用。

httpCompression

在 v1.4.0 中添加

默认值: true

是否为 HTTP 长轮询传输启用压缩。

请注意,如果 httpCompression 设置为 false,则在使用 HTTP 长轮询请求建立连接时,在发出时使用的压缩标志 (socket.compress(true).emit(...)) 将被忽略。

支持来自 Node.js zlib 模块 的所有选项。

示例

const io = new Server(httpServer, {
httpCompression: {
// Engine.IO options
threshold: 2048, // defaults to 1024
// Node.js zlib options
chunkSize: 8 * 1024, // defaults to 16 * 1024
windowBits: 14, // defaults to 15
memLevel: 7, // defaults to 8
}
});

maxHttpBufferSize

默认值:1e6 (1 MB)

这定义了单个消息在关闭套接字之前可以包含多少字节。您可以根据需要增加或减少此值。

const io = new Server(httpServer, {
maxHttpBufferSize: 1e8
});

它与 ws 包的 maxPayload 选项匹配。

perMessageDeflate

历史
版本更改
v3.0.0permessage-deflate 扩展现在默认情况下已禁用。
v1.4.0首次实现。

默认值: false

是否为 WebSocket 传输启用 permessage-deflate 扩展。众所周知,此扩展在性能和内存消耗方面会增加大量开销,因此我们建议仅在确实需要时才启用它。

请注意,如果 perMessageDeflate 设置为 false(这是默认值),则在使用 WebSockets 建立连接时,在发出时使用的压缩标志 (socket.compress(true).emit(...)) 将被忽略,因为 permessage-deflate 扩展不能在每个消息的基础上启用。

支持来自 ws 模块 的所有选项

const io = new Server(httpServer, {
perMessageDeflate: {
threshold: 2048, // defaults to 1024

zlibDeflateOptions: {
chunkSize: 8 * 1024, // defaults to 16 * 1024
},

zlibInflateOptions: {
windowBits: 14, // defaults to 15
memLevel: 7, // defaults to 8
},

clientNoContextTakeover: true, // defaults to negotiated value.
serverNoContextTakeover: true, // defaults to negotiated value.
serverMaxWindowBits: 10, // defaults to negotiated value.

concurrencyLimit: 20, // defaults to 10
}
});

pingInterval

默认值:25000

此值用于心跳机制,该机制定期检查服务器和客户端之间的连接是否仍然存活。

服务器每 pingInterval 毫秒发送一个 ping 数据包,如果客户端在 pingTimeout 毫秒内没有用 pong 响应,则服务器认为连接已关闭。

类似地,如果客户端在 pingInterval + pingTimeout 毫秒内没有从服务器收到 ping 数据包,则客户端也认为连接已关闭。

在这两种情况下,断开连接的原因将是:ping 超时

socket.on("disconnect", (reason) => {
console.log(reason); // "ping timeout"
});
注意

使用像 1000 这样的小值(每秒一次心跳)会给您的服务器带来一些负载,这在数千个连接的客户端中可能会变得明显。

pingTimeout

历史
版本更改
v4.0.0pingTimeout 现在默认为 20000 毫秒。
v2.1.0默认为 5000 毫秒。
v1.0.0默认为 60000 毫秒。

默认值:20000

参见 上面

注意

使用较小的值意味着暂时无响应的服务器可能会触发许多客户端重新连接。

相反,使用较大的值意味着断开的连接需要更长时间才能被检测到(如果 pingInterval + pingTimeout 大于 60 秒,您可能会在 React Native 上收到警告)。

transports

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

服务器端允许的低级传输。

启用 WebTransport 的示例

const io = new Server({
transports: ["polling", "websocket", "webtransport"]
});

请查看 WebTransport 示例 这里

另请参见:客户端 transports

upgradeTimeout

默认值:10000

这是取消未完成的传输升级之前的延迟(以毫秒为单位)。

wsEngine

默认值:require("ws").Server(源代码可以在 这里 找到)

要使用的 WebSocket 服务器实现。请参见 这里 的文档。

示例

const io = new Server(httpServer, {
wsEngine: require("eiows").Server
});