Skip to main content
Version: 4.x

客户端 API


IO

io 方法绑定到独立构建中的全局作用域:

英:The io method is bound to the global scope in the standalone build:

<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io();
</script>

自版本 4.3.0 起,还提供 ESM 打包包:

英:An ESM bundle is also available since version 4.3.0:

<script type="module">
import { io } from "https://cdn.socket.io/4.7.2/socket.io.esm.min.js";

const socket = io();
</script>

使用 导入映射

英:With an import map:

<script type="importmap">
{
"imports": {
"socket.io-client": "https://cdn.socket.io/4.7.2/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 包导入:

英:Else, in all other cases (with some build tools, in Node.js or React Native), it can be imported from the socket.io-client package:

// ES modules
import { io } from "socket.io-client";

// CommonJS
const { io } = require("socket.io-client");

io.protocol

协议修订号(当前:5)。

英:The protocol revision number (currently: 5).

该协议定义了客户端和服务器之间交换的数据包的格式。 客户端和服务器必须使用相同的版本才能相互理解。

英:The protocol defines the format of the packets exchanged between the client and the server. Both the client and the server must use the same revision in order to understand each other.

你可以找到更多信息 此处

英:You can find more information here.

io([url][, options])

为给定 URL 创建新的 Manager,并尝试在后续调用中重用现有的 Manager,除非 multiplex 选项与 false 一起传递。 传递此选项相当于传递 "force new connection": trueforceNew: true

英:Creates a new Manager for the given URL, and attempts to reuse an existing Manager for subsequent calls, unless the multiplex option is passed with false. Passing this option is the equivalent of passing "force new connection": true or forceNew: true.

为 URL 中的路径名指定的命名空间返回一个新的 Socket 实例,默认为 /。 例如,如果 urlhttp://localhost/users,则将建立到 http://localhost 的传输连接,以及将建立到 /users 的 Socket.IO 连接。

英:A new Socket instance is returned for the namespace specified by the pathname in the URL, defaulting to /. For example, if the url is http://localhost/users, a transport connection will be established to http://localhost and a Socket.IO connection will be established to /users.

还可以使用 query 选项或直接在 url 中提供查询参数(例如:http://localhost/users?token=abc)。

英:Query parameters can also be provided, either with the query option or directly in the url (example: http://localhost/users?token=abc).

要了解幕后发生的情况,请看以下示例:

英:To understand what happens under the hood, the following example:

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

const socket = io("ws://example.com/my-namespace", {
reconnectionDelayMax: 10000,
auth: {
token: "123"
},
query: {
"my-key": "my-value"
}
});

是以下内容的简短版本:

英:is the short version of:

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

可用选项的完整列表可在 此处 中找到。

英:The complete list of available options can be found here.

管理者

Manager in the class diagram for the clientManager in the class diagram for the client

Manager 管理 Engine.IO client 实例,它是建立与服务器的连接的底层引擎(通过使用 WebSocket 或 HTTP 长轮询等传输)。

英:The Manager manages the Engine.IO client instance, which is the low-level engine that establishes the connection to the server (by using transports like WebSocket or HTTP long-polling).

Manager 处理重新连接逻辑。

英:The Manager handles the reconnection logic.

一个 Manager 可以被多个 插座 使用。 你可以找到有关此多路复用功能 此处 的更多信息。

英:A single Manager can be used by several Sockets. You can find more information about this multiplexing feature here.

请注意,在大多数情况下,你不会直接使用 Manager,而是使用 套接字 实例。

英:Please note that, in most cases, you won't use the Manager directly but use the Socket instance instead.

构造函数

new Manager(url[, options])

可用选项的完整列表可在 此处 中找到。

英:The complete list of available options can be found here.

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'

因连接错误而触发。

英:Fired upon a connection error.

socket.io.on("error", (error) => {
// ...
});

事件: 'ping'

当从服务器收到 ping 数据包时触发。

英:Fired when a ping packet is received from the server.

socket.io.on("ping", () => {
// ...
});

事件: 'reconnect'

  • attempt <number> 重新连接尝试次数

成功重新连接后触发。

英:Fired upon a successful reconnection.

socket.io.on("reconnect", (attempt) => {
// ...
});

事件: 'reconnect_attempt'

  • attempt <number> 重新连接尝试次数

尝试重新连接时触发。

英:Fired upon an attempt to reconnect.

socket.io.on("reconnect_attempt", (attempt) => {
// ...
});

事件: 'reconnect_error'

重新连接尝试错误时触发。

英:Fired upon a reconnection attempt error.

socket.io.on("reconnect_error", (error) => {
// ...
});

事件: 'reconnect_failed'

当无法在 reconnectionAttempts 内重新连接时触发。

英:Fired when couldn't reconnect within reconnectionAttempts.

socket.io.on("reconnect_failed", () => {
// ...
});

方法

manager.connect([callback])

manager.open([callback]).

英:Synonym of manager.open([callback]).

manager.open([callback])

如果管理器是使用 autoConnectfalse 启动的,则启动新的连接尝试。

英:If the manager was initiated with autoConnect to false, launch a new connection attempt.

callback 参数是可选的,一旦尝试失败/成功就会被调用。

英:The callback argument is optional and will be called once the attempt fails/succeeds.

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 选项,如果没有传递参数则返回它。

英:Sets the reconnection option, or returns it if no parameters are passed.

manager.reconnectionAttempts([value])

设置 reconnectionAttempts 选项,如果没有传递参数则返回它。

英:Sets the reconnectionAttempts option, or returns it if no parameters are passed.

manager.reconnectionDelay([value])

设置 reconnectionDelay 选项,如果没有传递参数则返回它。

英:Sets the reconnectionDelay option, or returns it if no parameters are passed.

manager.reconnectionDelayMax([value])

设置 reconnectionDelayMax 选项,如果没有传递参数则返回它。

英:Sets the reconnectionDelayMax option, or returns it if no parameters are passed.

manager.socket(nsp, options)

为给定命名空间创建一个新的 Socket。 从 options 对象中仅读取 auth ({ auth: {key: "value"} })。 其他键将被忽略,并应在实例化 new Manager(nsp, options) 时传递。

英:Creates a new Socket for the given namespace. Only auth ({ auth: {key: "value"} }) is read from the options object. Other keys will be ignored and should be passed when instancing a new Manager(nsp, options).

manager.timeout([value])

设置 timeout 选项,如果没有传递参数则返回它。

英:Sets the timeout option, or returns it if no parameters are passed.

套接字

Socket in the class diagram for the clientSocket in the class diagram for the client

Socket 是与服务器交互的基本类。 Socket 属于某个 命名空间(默认为 /),并使用底层 管理者 进行通信。

英:A Socket is the fundamental class for interacting with the server. A Socket belongs to a certain Namespace (by default /) and uses an underlying Manager to communicate.

Socket 基本上是 EventEmitter,它将事件发送到 — 并接收来自的事件 — 网络上的服务器。

英:A Socket is basically an EventEmitter which sends events to — and receive events from — the server over the network.

socket.emit("hello", { a: "b", c: [] });

socket.on("hey", (...args) => {
// ...
});

更多信息可参见 此处

英:More information can be found here.

事件

事件: 'connect'

连接到命名空间时触发(包括成功重新连接)。

英:Fired upon connection to the Namespace (including a successful reconnection).

socket.on("connect", () => {
// ...
});
caution

请注意,你不应在 connect 处理程序本身中注册事件处理程序,因为每次 Socket 重新连接时都会注册一个新的处理程序:

英:Please note that you shouldn't register event handlers in the connect handler itself, as a new handler will be registered every time the Socket reconnects:

// BAD
socket.on("connect", () => {
socket.on("data", () => { /* ... */ });
});

// GOOD
socket.on("connect", () => { /* ... */ });
socket.on("data", () => { /* ... */ });

事件: 'disconnect'

  • reason <string>
  • details <DisconnectDetails>

断开连接时触发。 可能的断开原因列表:

英:Fired upon disconnection. The list of possible disconnection reasons:

原因描述
io server disconnect服务器已强制断开与 socket.disconnect() 的套接字
io client disconnect使用 socket.disconnect() 手动断开套接字
ping timeout服务器未发送 pingInterval + pingTimeout 范围内的 PING
transport close连接已关闭(例如:用户失去连接,或网络从 WiFi 更改为 4G)
transport error连接遇到错误(例如:服务器在 HTTP 长轮询周期期间被终止)

在前两种情况下(显式断开连接),客户端不会尝试重新连接,需要手动调用 socket.connect()

英:In the first two cases (explicit disconnection), the client will not try to reconnect and you need to manually call socket.connect().

在所有其他情况下,客户端将等待一个小的 随机延迟,然后尝试重新连接:

英:In all other cases, the client will wait for a small random delay and then try to reconnect:

socket.on("disconnect", (reason) => {
if (reason === "io server disconnect") {
// the disconnection was initiated by the server, you need to reconnect manually
socket.connect();
}
// else the socket will automatically try to reconnect
});

事件: 'connect_error'

当命名空间中间件发生错误时触发。

英:Fired when a namespace middleware error occurs.

socket.on("connect_error", (error) => {
// ...
});

属性

socket.connected

套接字是否连接到服务器。

英:Whether or not the socket is connected to the server.

const socket = io("http://localhost");

socket.on("connect", () => {
console.log(socket.connected); // true
});

socket.disconnected

套接字是否与服务器断开连接。

英:Whether or not the socket is disconnected from the server.

const socket = io("http://localhost");

socket.on("connect", () => {
console.log(socket.disconnected); // false
});

socket.id

套接字会话的唯一标识符。 在 connect 事件触发后设置,在 reconnect 事件后更新。

英:A unique identifier for the socket session. Set after the connect event is triggered, and updated after the reconnect event.

const socket = io("http://localhost");

console.log(socket.id); // undefined

socket.on("connect", () => {
console.log(socket.id); // "G5p5..."
});
caution

id 属性是 ephemeral ID,不应在你的应用中使用(或仅用于调试目的),因为:

英:The id attribute is an ephemeral ID that is not meant to be used in your application (or only for debugging purposes) because:

  • 每次重新连接后都会重新生成此 ID(例如当 WebSocket 连接被切断时,或者当用户刷新页面时)
  • 两个不同的浏览器选项卡将有两个不同的 ID
  • 服务器上没有为给定 ID 存储消息队列(即如果客户端断开连接,从服务器发送到该 ID 的消息就会丢失)

请改用常规会话 ID(在 cookie 中发送,或存储在 localStorage 中并在 auth 有效负载中发送)。

英:Please use a regular session ID instead (either sent in a cookie, or stored in the localStorage and sent in the auth payload).

也可以看看:

英:See also:

socket.io

对底层 管理者 的引用。

英:A reference to the underlying 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 中添加

英:Added in v4.6.0

上次重新连接时连接状态是否成功恢复。

英:Whether the connection state was successfully recovered during the last reconnection.

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

有关此功能的更多信息 此处

英:More information about this feature here.

方法

socket.close()

v1.0.0 中添加

英:Added in v1.0.0

socket.disconnect() 的同义词。

英:Synonym of socket.disconnect().

socket.compress(value)

设置后续事件触发的修饰符,仅当值为 true 时才会压缩事件数据。 当你不调用该方法时默认为 true

英:Sets a modifier for a subsequent event emission that the event data will only be compressed if the value is true. Defaults to true when you don't call the method.

socket.compress(false).emit("an event", { some: "data" });

socket.connect()

v1.0.0 中添加

英:Added in v1.0.0

  • 返回 Socket

手动连接套接字。

英:Manually connects the socket.

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

// ...
socket.connect();

它还可用于手动重新连接:

英:It can also be used to manually reconnect:

socket.on("disconnect", () => {
socket.connect();
});

socket.disconnect()

v1.0.0 中添加

英:Added in v1.0.0

手动断开套接字。 在这种情况下,套接字将不会尝试重新连接。

英:Manually disconnects the socket. In that case, the socket will not try to reconnect.

相关断线原因:

英:Associated disconnection reason:

  • client-side: "io client disconnect"
  • server-side: "client namespace disconnect"

如果这是 Manager 的最后一个活动 Socket 实例,则底层连接将被关闭。

英:If this is the last active Socket instance of the Manager, the low-level connection will be closed.

socket.emit(eventName[, ...args][, ack])

向由字符串名称标识的套接字触发事件。 可以包括任何其他参数。 支持所有可序列化的数据结构,包括 Buffer

英:Emits an event to the socket identified by the string name. Any other parameters can be included. All serializable data structures are supported, including Buffer.

socket.emit("hello", "world");
socket.emit("with-binary", 1, "2", { 3: "4", 5: Buffer.from([6, 7, 8]) });

ack 参数是可选的,将与服务器应答一起调用。

英:The ack argument is optional and will be called with the server answer.

客户端

英:Client

socket.emit("hello", "world", (response) => {
console.log(response); // "got it"
});

服务器

英:Server

io.on("connection", (socket) => {
socket.on("hello", (arg, callback) => {
console.log(arg); // "world"
callback("got it");
});
});

socket.emitWithAck(eventName[, ...args])

v4.6.0 中添加

英:Added in v4.6.0

基于 promise 的版本,发出并期待服务器的确认:

英:Promised-based version of emitting and expecting an acknowledgement from the server:

// 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
}

上面的例子相当于:

英:The example above is equivalent to:

// without timeout
socket.emit("hello", "world", (val) => {
// ...
});

// with a specific timeout
socket.timeout(10000).emitWithAck("hello", "world", (err, val) => {
// ...
});

在接收端:

英:And on the receiving side:

io.on("connection", (socket) => {
socket.on("hello", (arg1, callback) => {
callback("got it"); // only one argument is expected
});
});
caution

不支持 Promise 需要添加 polyfill 才能使用此功能的环境。

英:Environments that do not support Promises will need to add a polyfill in order to use this feature.

socket.listeners(eventName)

继承自 EventEmitter 类

英:Inherited from the EventEmitter class.

返回名为 eventName 的事件的监听器数组。

英:Returns the array of listeners for the event named eventName.

socket.on("my-event", () => {
// ...
});

console.log(socket.listeners("my-event")); // prints [ [Function] ]

socket.listenersAny()

v3.0.0 中添加

英:Added in v3.0.0

返回已注册的捕获所有监听器的列表。

英:Returns the list of registered catch-all listeners.

const listeners = socket.listenersAny();

socket.listenersAnyOutgoing()

v4.5.0 中添加

英:Added in v4.5.0

返回已注册的传出数据包捕获所有监听器的列表。

英:Returns the list of registered catch-all listeners for outgoing packets.

const listeners = socket.listenersAnyOutgoing();

socket.off([eventName][, listener])

继承自 EventEmitter 类

英:Inherited from the EventEmitter class.

从名为 eventName 的事件的监听器数组中删除指定的 listener

英:Removes the specified listener from the listener array for the event named eventName.

const myListener = () => {
// ...
}

socket.on("my-event", myListener);

// then later
socket.off("my-event", myListener);

listener 参数也可以省略:

英:The listener argument can also be omitted:

// remove all listeners for that event
socket.off("my-event");

// remove all listeners for all events
socket.off();

socket.offAny([listener])

v3.0.0 中添加

英:Added in v3.0.0

删除先前注册的监听器。 如果未提供监听器,则删除所有捕获所有监听器。

英:Removes the previously registered listener. If no listener is provided, all catch-all listeners are removed.

const myListener = () => { /* ... */ };

socket.onAny(myListener);

// then, later
socket.offAny(myListener);

socket.offAny();

socket.offAnyOutgoing([listener])

v4.5.0 中添加

英:Added in v4.5.0

删除先前注册的监听器。 如果未提供监听器,则删除所有捕获所有监听器。

英:Removes the previously registered listener. If no listener is provided, all catch-all listeners are removed.

const myListener = () => { /* ... */ };

socket.onAnyOutgoing(myListener);

// remove a single listener
socket.offAnyOutgoing(myListener);

// remove all listeners
socket.offAnyOutgoing();

socket.on(eventName, callback)

继承自 EventEmitter 类

英:Inherited from the EventEmitter class.

为给定事件注册一个新的处理程序。

英:Register a new handler for the given event.

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 中添加

英:Added in v3.0.0

注册一个新的包罗万象的监听器。

英:Register a new catch-all listener.

socket.onAny((event, ...args) => {
console.log(`got ${event}`);
});
caution

回执 没有被捕获在包罗万象的监听器中。

英:Acknowledgements are not caught in the catch-all listener.

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 中添加

英:Added in v4.5.0

为传出数据包注册一个新的捕获所有监听器。

英:Register a new catch-all listener for outgoing packets.

socket.onAnyOutgoing((event, ...args) => {
console.log(`got ${event}`);
});
caution

回执 没有被捕获在包罗万象的监听器中。

英:Acknowledgements are not caught in the catch-all listener.

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 类

英:Inherited from the EventEmitter class.

为名为 eventName 的事件添加一次性 listener 函数。 下次触发 eventName 时,该监听器将被删除,然后被调用。

英:Adds a one-time listener function for the event named eventName. The next time eventName is triggered, this listener is removed and then invoked.

socket.once("my-event", () => {
// ...
});

socket.open()

v1.0.0 中添加

英:Added in v1.0.0

socket.connect() 的同义词。

英:Synonym of socket.connect().

socket.prependAny(callback)

v3.0.0 中添加

英:Added in v3.0.0

注册一个新的包罗万象的监听器。 监听器被添加到监听器数组的开头。

英:Register a new catch-all listener. The listener is added to the beginning of the listeners array.

socket.prependAny((event, ...args) => {
console.log(`got ${event}`);
});

socket.prependAnyOutgoing(callback)

v4.5.0 中添加

英:Added in v4.5.0

为传出数据包注册一个新的捕获所有监听器。 监听器被添加到监听器数组的开头。

英:Register a new catch-all listener for outgoing packets. The listener is added to the beginning of the listeners array.

socket.prependAnyOutgoing((event, ...args) => {
console.log(`got ${event}`);
});

socket.send([...args][, ack])

发送 message 事件。 请参阅 socket.emit(eventName[, ...args][, ack])

英:Sends a message event. See socket.emit(eventName[, ...args][, ack]).

socket.timeout(value)

v4.4.0 中添加

英:Added in v4.4.0

为后续事件触发设置一个修饰符,当给定的毫秒数过去而没有服务器确认时,将调用回调并出现错误:

英:Sets a modifier for a subsequent event emission that the callback will be called with an error when the given number of milliseconds have elapsed without an acknowledgement from the server:

socket.timeout(5000).emit("my-event", (err) => {
if (err) {
// the server did not acknowledge the event in the given delay
}
});

标志

标志: 'volatile'

v3.0.0 中添加

英:Added in v3.0.0

为后续事件触发设置修饰符,指示在以下情况下可能会丢弃数据包:

英:Sets a modifier for the subsequent event emission indicating that the packet may be dropped if:

  • 插座未连接
  • 底层传输不可写(例如,当 POST 请求已在 HTTP 长轮询模式下运行时)
socket.volatile.emit(/* ... */); // the server may or may not receive it