客户端 API
IO
io
方法绑定到独立构建中的全局范围
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io();
</script>
自版本 4.3.0 起,还提供 ESM 包
<script type="module">
import { io } from "https://cdn.socket.io/4.7.5/socket.io.esm.min.js";
const socket = io();
</script>
使用 导入映射
<script type="importmap">
{
"imports": {
"socket.io-client": "https://cdn.socket.io/4.7.5/socket.io.esm.min.js"
}
}
</script>
<script type="module">
import { io } from "socket.io-client";
const socket = io();
</script>
否则,在所有其他情况下(使用某些构建工具,在 Node.js 或 React Native 中),它可以从 socket.io-client
包中导入
// ES modules
import { io } from "socket.io-client";
// CommonJS
const { io } = require("socket.io-client");
io.protocol
协议修订号(当前:5)。
协议定义了客户端和服务器之间交换的数据包格式。客户端和服务器都必须使用相同的修订版才能相互理解。
您可以在 此处 找到更多信息。
io([url][, options])
为给定 URL 创建新的 Manager
,并尝试为后续调用重用现有 Manager
,除非使用 false
传递 multiplex
选项。传递此选项等同于传递 "force new connection": true
或 forceNew: true
。
为 URL 中路径名指定的命名空间返回新的 Socket
实例,默认为 /
。例如,如果 url
为 http://localhost/users
,则将建立到 http://localhost
的传输连接,并将建立到 /users
的 Socket.IO 连接。
也可以提供查询参数,使用 query
选项或直接在 url 中提供(例如:http://localhost/users?token=abc
)。
为了理解幕后发生的事情,以下示例
import { io } from "socket.io-client";
const socket = io("ws://example.com/my-namespace", {
reconnectionDelayMax: 10000,
auth: {
token: "123"
},
query: {
"my-key": "my-value"
}
});
是简短版本
import { Manager } from "socket.io-client";
const manager = new Manager("ws://example.com", {
reconnectionDelayMax: 10000,
query: {
"my-key": "my-value"
}
});
const socket = manager.socket("/my-namespace", {
auth: {
token: "123"
}
});
可以在 此处 找到所有可用选项的完整列表。
Manager


Manager
管理 Engine.IO 客户端 实例,它是建立与服务器连接的低级引擎(通过使用 WebSocket 或 HTTP 长轮询等传输)。
Manager
处理重新连接逻辑。
单个 Manager
可以被多个 Sockets 使用。您可以在 此处 找到有关此多路复用功能的更多信息。
请注意,在大多数情况下,您不会直接使用 Manager,而是使用 Socket 实例。
构造函数
new Manager(url[, options])
可以在 此处 找到所有可用选项的完整列表。
import { Manager } from "socket.io-client";
const manager = new Manager("https://example.com");
const socket = manager.socket("/"); // main namespace
const adminSocket = manager.socket("/admin"); // admin namespace
事件
事件: 'error'
error
<Error>
错误对象
在连接错误时触发。
socket.io.on("error", (error) => {
// ...
});
事件: 'ping'
从服务器收到 ping 数据包时触发。
socket.io.on("ping", () => {
// ...
});
事件: 'reconnect'
attempt
<number>
重新连接尝试次数
在成功重新连接时触发。
socket.io.on("reconnect", (attempt) => {
// ...
});
事件: 'reconnect_attempt'
attempt
<number>
重新连接尝试次数
在尝试重新连接时触发。
socket.io.on("reconnect_attempt", (attempt) => {
// ...
});
事件: 'reconnect_error'
error
<Error>
错误对象
在重新连接尝试错误时触发。
socket.io.on("reconnect_error", (error) => {
// ...
});
事件: 'reconnect_failed'
在无法在 reconnectionAttempts
内重新连接时触发。
socket.io.on("reconnect_failed", () => {
// ...
});
方法
manager.connect([callback])
是 manager.open([callback]) 的同义词。
manager.open([callback])
callback
<Function>
- 返回
<Manager>
如果 manager 使用 autoConnect
初始化为 false
,则启动新的连接尝试。
callback
参数是可选的,将在尝试失败/成功后调用。
import { Manager } from "socket.io-client";
const manager = new Manager("https://example.com", {
autoConnect: false
});
const socket = manager.socket("/");
manager.open((err) => {
if (err) {
// an error has occurred
} else {
// the connection was successfully established
}
});
manager.reconnection([value])
设置 reconnection
选项,或者如果未传递参数,则返回它。
manager.reconnectionAttempts([value])
设置 reconnectionAttempts
选项,或者如果未传递参数,则返回它。
manager.reconnectionDelay([value])
设置 reconnectionDelay
选项,或者如果未传递参数,则返回它。
manager.reconnectionDelayMax([value])
设置 reconnectionDelayMax
选项,或者如果未传递参数,则返回它。
manager.socket(nsp, options)
为给定命名空间创建一个新的 Socket
。仅从 options
对象中读取 auth
({ auth: {key: "value"} }
)。其他键将被忽略,应在实例化 new Manager(nsp, options)
时传递。
manager.timeout([value])
设置 timeout
选项,或者如果未传递参数,则返回它。
Socket


Socket
是与服务器交互的基本类。Socket
属于某个 命名空间(默认情况下为 /
),并使用底层的 Manager 进行通信。
Socket
本质上是一个 EventEmitter,它通过网络向服务器发送事件,并从服务器接收事件。
socket.emit("hello", { a: "b", c: [] });
socket.on("hey", (...args) => {
// ...
});
可以在 此处 找到更多信息。
事件
事件: 'connect'
此事件在 Socket 实例连接和重新连接时触发。
socket.on("connect", () => {
// ...
});
事件处理程序不应在 connect
处理程序本身中注册,因为每次 socket 实例重新连接时都会注册一个新的处理程序
错误 ⚠️
socket.on("connect", () => {
socket.on("data", () => { /* ... */ });
});
正确 👍
socket.on("connect", () => {
// ...
});
socket.on("data", () => { /* ... */ });
事件: 'connect_error'
error
<Error>
此事件在连接失败时触发。
原因 | 自动重新连接? |
---|---|
无法建立低级连接(临时故障) | ✅ 是 |
服务器在 中间件函数 中拒绝了连接 | ❌ 否 |
socket.active
属性指示 socket 是否会在短暂的 随机延迟 后自动尝试重新连接
socket.on("connect_error", (error) => {
if (socket.active) {
// temporary failure, the socket will automatically try to reconnect
} else {
// the connection was denied by the server
// in that case, `socket.connect()` must be manually called in order to reconnect
console.log(error.message);
}
});
事件: 'disconnect'
reason
<string>
details
<DisconnectDetails>
此事件在断开连接时触发。
socket.on("disconnect", (reason, details) => {
// ...
});
以下是可能的理由列表
原因 | 描述 | 自动重新连接? |
---|---|---|
io 服务器断开连接 | 服务器使用 socket.disconnect() 强制断开了 socket 连接 | ❌ 否 |
io 客户端断开连接 | 使用 socket.disconnect() 手动断开了 socket 连接 | ❌ 否 |
ping 超时 | 服务器在 pingInterval + pingTimeout 范围内未发送 PING | ✅ 是 |
传输关闭 | 连接已关闭(例如:用户已断开连接,或网络从 Wi-Fi 切换到 4G)。 | ✅ 是 |
传输错误 | 连接遇到错误(例如:服务器在 HTTP 长轮询周期中被终止)。 | ✅ 是 |
socket.active
属性指示 socket 是否会在短暂的 随机延迟 后自动尝试重新连接
socket.on("disconnect", (reason) => {
if (socket.active) {
// temporary disconnection, the socket will automatically try to reconnect
} else {
// the connection was forcefully closed by the server or the client itself
// in that case, `socket.connect()` must be manually called in order to reconnect
console.log(reason);
}
});
属性
socket.active
是否自动尝试重新连接。
此属性可以在连接失败后使用
socket.on("connect_error", (error) => {
if (socket.active) {
// temporary failure, the socket will automatically try to reconnect
} else {
// the connection was denied by the server
// in that case, `socket.connect()` must be manually called in order to reconnect
console.log(error.message);
}
});
或断开连接后使用
socket.on("disconnect", (reason) => {
if (socket.active) {
// temporary disconnection, the socket will automatically try to reconnect
} else {
// the connection was forcefully closed by the server or the client itself
// in that case, `socket.connect()` must be manually called in order to reconnect
console.log(reason);
}
});
socket.connected
套接字当前是否已连接到服务器。
const socket = io();
console.log(socket.connected); // false
socket.on("connect", () => {
console.log(socket.connected); // true
});
socket.disconnected
套接字当前是否已断开与服务器的连接。
const socket = io();
console.log(socket.disconnected); // true
socket.on("connect", () => {
console.log(socket.disconnected); // false
});
socket.id
套接字会话的唯一标识符。在触发 connect
事件后设置,并在 reconnect
事件后更新。
const socket = io();
console.log(socket.id); // undefined
socket.on("connect", () => {
console.log(socket.id); // "G5p5..."
});
id
属性是一个短暂的 ID,不应在您的应用程序中使用(或仅用于调试目的),因为
- 此 ID 在每次重新连接后都会重新生成(例如,当 WebSocket 连接断开时,或当用户刷新页面时)。
- 两个不同的浏览器标签将具有两个不同的 ID。
- 服务器上没有为给定 ID 存储消息队列(即,如果客户端断开连接,则从服务器发送到此 ID 的消息将丢失)。
请改用常规会话 ID(通过 cookie 发送,或存储在 localStorage 中并发送到 auth
负载中)。
另请参见
socket.io
对底层 Manager 的引用。
socket.on("connect", () => {
const engine = socket.io.engine;
console.log(engine.transport.name); // in most cases, prints "polling"
engine.once("upgrade", () => {
// called when the transport is upgraded (i.e. from HTTP long-polling to WebSocket)
console.log(engine.transport.name); // in most cases, prints "websocket"
});
engine.on("packet", ({ type, data }) => {
// called for each packet received
});
engine.on("packetCreate", ({ type, data }) => {
// called for each packet sent
});
engine.on("drain", () => {
// called when the write buffer is drained
});
engine.on("close", (reason) => {
// called when the underlying connection is closed
});
});
socket.recovered
在 v4.6.0 中添加
连接状态是否在上次重新连接期间成功恢复。
socket.on("connect", () => {
if (socket.recovered) {
// any event missed during the disconnection period will be received now
} else {
// new or unrecoverable session
}
});
有关此功能的更多信息,请 点击这里。
方法
socket.close()
在 v1.0.0 中添加
socket.disconnect() 的同义词。
socket.compress(value)
为后续事件发射设置一个修饰符,指示事件数据仅在值为 true
时才压缩。默认情况下,如果您不调用此方法,则为 true
。
socket.compress(false).emit("an event", { some: "data" });
socket.connect()
在 v1.0.0 中添加
- 返回值
Socket
手动连接套接字。
const socket = io({
autoConnect: false
});
// ...
socket.connect();
它也可以用于手动重新连接
socket.on("disconnect", () => {
socket.connect();
});
socket.disconnect()
在 v1.0.0 中添加
- 返回
<Socket>
手动断开套接字连接。在这种情况下,套接字将不会尝试重新连接。
关联的断开连接原因
- 客户端:
"io client disconnect"
- 服务器端:
"client namespace disconnect"
如果这是 Manager 的最后一个活动 Socket 实例,则低级连接将被关闭。
socket.emit(eventName[, ...args][, ack])
eventName
<string>
|<symbol>
args
<any[]>
ack
<Function>
- 返回值
true
向由字符串名称标识的套接字发出事件。可以包含任何其他参数。所有可序列化数据结构都受支持,包括 Buffer
。
socket.emit("hello", "world");
socket.emit("with-binary", 1, "2", { 3: "4", 5: Buffer.from([6, 7, 8]) });
ack
参数是可选的,将使用服务器答案进行调用。
客户端
socket.emit("hello", "world", (response) => {
console.log(response); // "got it"
});
服务器
io.on("connection", (socket) => {
socket.on("hello", (arg, callback) => {
console.log(arg); // "world"
callback("got it");
});
});
socket.emitWithAck(eventName[, ...args])
在 v4.6.0 中添加
eventName
<string>
|<symbol>
args
any[]
- 返回值
Promise<any>
基于 Promise 的发出事件并期望服务器确认的版本
// without timeout
const response = await socket.emitWithAck("hello", "world");
// with a specific timeout
try {
const response = await socket.timeout(10000).emitWithAck("hello", "world");
} catch (err) {
// the server did not acknowledge the event in the given delay
}
上面的示例等效于
// without timeout
socket.emit("hello", "world", (val) => {
// ...
});
// with a specific timeout
socket.timeout(10000).emit("hello", "world", (err, val) => {
// ...
});
在接收端
io.on("connection", (socket) => {
socket.on("hello", (arg1, callback) => {
callback("got it"); // only one argument is expected
});
});
不支持 Promise 的环境需要添加 polyfill 才能使用此功能。
socket.listeners(eventName)
继承自 EventEmitter 类。
eventName
<string>
|<symbol>
- 返回值
<Function[]>
返回名为 eventName
的事件的监听器数组。
socket.on("my-event", () => {
// ...
});
console.log(socket.listeners("my-event")); // prints [ [Function] ]
socket.listenersAny()
在 v3.0.0 中添加
- 返回值
<Function[]>
返回已注册的通配符监听器列表。
const listeners = socket.listenersAny();
socket.listenersAnyOutgoing()
在 v4.5.0 中添加
- 返回值
<Function[]>
返回已注册的用于出站数据包的通配符监听器列表。
const listeners = socket.listenersAnyOutgoing();
socket.off([eventName][, listener])
继承自 EventEmitter 类。
eventName
<string>
|<symbol>
listener
<Function>
- 返回
<Socket>
从名为 eventName
的事件的监听器数组中删除指定的 listener
。
const myListener = () => {
// ...
}
socket.on("my-event", myListener);
// then later
socket.off("my-event", myListener);
listener
参数也可以省略
// remove all listeners for that event
socket.off("my-event");
// remove all listeners for all events
socket.off();
socket.offAny([listener])
在 v3.0.0 中添加
listener
<Function>
删除先前注册的监听器。如果没有提供监听器,则删除所有通配符监听器。
const myListener = () => { /* ... */ };
socket.onAny(myListener);
// then, later
socket.offAny(myListener);
socket.offAny();
socket.offAnyOutgoing([listener])
在 v4.5.0 中添加
listener
<Function>
删除先前注册的监听器。如果没有提供监听器,则删除所有通配符监听器。
const myListener = () => { /* ... */ };
socket.onAnyOutgoing(myListener);
// remove a single listener
socket.offAnyOutgoing(myListener);
// remove all listeners
socket.offAnyOutgoing();
socket.on(eventName, callback)
继承自 EventEmitter 类。
eventName
<string>
|<symbol>
listener
<Function>
- 返回
<Socket>
为给定事件注册一个新的处理程序。
socket.on("news", (data) => {
console.log(data);
});
// with multiple arguments
socket.on("news", (arg1, arg2, arg3, arg4) => {
// ...
});
// with callback
socket.on("news", (cb) => {
cb(0);
});
socket.onAny(callback)
在 v3.0.0 中添加
callback
<Function>
注册一个新的通配符监听器。
socket.onAny((event, ...args) => {
console.log(`got ${event}`);
});
确认 不会被通配符监听器捕获。
socket.emit("foo", (value) => {
// ...
});
socket.onAnyOutgoing(() => {
// triggered when the event is sent
});
socket.onAny(() => {
// not triggered when the acknowledgement is received
});
socket.onAnyOutgoing(callback)
在 v4.5.0 中添加
callback
<Function>
为出站数据包注册一个新的通配符监听器。
socket.onAnyOutgoing((event, ...args) => {
console.log(`got ${event}`);
});
确认 不会被通配符监听器捕获。
socket.on("foo", (value, callback) => {
callback("OK");
});
socket.onAny(() => {
// triggered when the event is received
});
socket.onAnyOutgoing(() => {
// not triggered when the acknowledgement is sent
});
socket.once(eventName, callback)
继承自 EventEmitter 类。
eventName
<string>
|<symbol>
listener
<Function>
- 返回
<Socket>
为名为 eventName
的事件添加一次性 listener
函数。下次触发 eventName
时,此监听器将被删除,然后调用。
socket.once("my-event", () => {
// ...
});
socket.open()
在 v1.0.0 中添加
socket.connect() 的同义词。
socket.prependAny(callback)
在 v3.0.0 中添加
callback
<Function>
注册一个新的通配符监听器。监听器被添加到监听器数组的开头。
socket.prependAny((event, ...args) => {
console.log(`got ${event}`);
});
socket.prependAnyOutgoing(callback)
在 v4.5.0 中添加
callback
<Function>
为出站数据包注册一个新的通配符监听器。监听器被添加到监听器数组的开头。
socket.prependAnyOutgoing((event, ...args) => {
console.log(`got ${event}`);
});
socket.send([...args][, ack])
args
<any[]>
ack
<Function>
- 返回
<Socket>
发送 message
事件。请参阅 socket.emit(eventName[, ...args][, ack])。
socket.timeout(value)
在 v4.4.0 中添加
为后续事件发射设置一个修饰符,指示当给定毫秒数过去而没有收到服务器的确认时,回调将使用错误进行调用
socket.timeout(5000).emit("my-event", (err) => {
if (err) {
// the server did not acknowledge the event in the given delay
}
});
标志
标志:'volatile'
在 v3.0.0 中添加
为后续事件发射设置一个修饰符,指示如果
- 套接字未连接
- 低级传输不可写(例如,当 HTTP 长轮询模式中已在运行
POST
请求时)
socket.volatile.emit(/* ... */); // the server may or may not receive it