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.5/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.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 包导入:

¥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

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.

构造函数

¥Constructor

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

事件

¥Events

事件:'错误'

¥Event: 'error'

因连接错误而触发。

¥Fired upon a connection error.

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

事件:'乒'

¥Event: 'ping'

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

¥Fired when a ping packet is received from the server.

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

事件:'重新连接'

¥Event: 'reconnect'

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

    ¥attempt <number> reconnection attempt number

成功重新连接后触发。

¥Fired upon a successful reconnection.

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

事件:'重新连接尝试'

¥Event: 'reconnect_attempt'

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

    ¥attempt <number> reconnection attempt number

尝试重新连接时触发。

¥Fired upon an attempt to reconnect.

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

事件:'重新连接错误'

¥Event: 'reconnect_error'

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

¥Fired upon a reconnection attempt error.

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

事件:'重新连接失败'

¥Event: 'reconnect_failed'

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

¥Fired when couldn't reconnect within reconnectionAttempts.

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

方法

¥Methods

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

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.

事件

¥Events

事件:'connect'

¥Event: 'connect'

该事件由 Socket 实例在连接和重新连接时触发。

¥This event is fired by the Socket instance upon connection and reconnection.

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

事件处理程序不应在 connect 处理程序本身中注册,因为每次套接字实例重新连接时都会注册一个新的处理程序:

¥Event handlers shouldn't be registered in the connect handler itself, as a new handler will be registered every time the socket instance reconnects:

不好:警告:

¥BAD ⚠️

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

GOOD 👍

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

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

事件:'连接错误'

¥Event: 'connect_error'

连接失败时会触发此事件。

¥This event is fired upon connection failure.

原因自动重连?
无法建立底层连接(暂时失败):白色复选标记:是的
连接在 中间件函数 中被服务器拒绝:X:不

socket.active 属性表示 socket 是否会在小 随机延迟 后自动尝试重新连接:

¥The socket.active attribute indicates whether the socket will automatically try to reconnect after a small randomized delay:

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'

¥Event: 'disconnect'

  • reason <string>

  • details <DisconnectDetails>

断开连接时会触发此事件。

¥This event is fired upon disconnection.

socket.on("disconnect", (reason, details) => {
// ...
});

以下是可能原因的列表:

¥Here is the list of possible reasons:

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

socket.active 属性表示 socket 是否会在小 随机延迟 后自动尝试重新连接:

¥The socket.active attribute indicates whether the socket will automatically try to reconnect after a small randomized delay:

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

属性

¥Attributes

socket.active

套接字是否会自动尝试重新连接。

¥Whether the socket will automatically try to reconnect.

连接失败后可以使用该属性:

¥This attribute can be used after a connection failure:

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

或者断开连接后:

¥Or after a disconnection:

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

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

¥Whether the socket is currently connected to the server.

const socket = io();

console.log(socket.connected); // false

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

socket.disconnected

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

¥Whether the socket is currently disconnected from the server.

const socket = io();

console.log(socket.disconnected); // true

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();

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

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

id 属性是一个临时 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 连接被切断时,或者当用户刷新页面时)

    ¥this ID is regenerated after each reconnection (for example when the WebSocket connection is severed, or when the user refreshes the page)

  • 两个不同的浏览器选项卡将有两个不同的 ID

    ¥two different browser tabs will have two different IDs

  • 服务器上没有为给定 ID 存储消息队列(即如果客户端断开连接,从服务器发送到该 ID 的消息就会丢失)

    ¥there is no message queue stored for a given ID on the server (i.e. if the client is disconnected, the messages sent from the server to this ID are lost)

请改用常规会话 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.

方法

¥Methods

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

    ¥Returns 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:

  • 客户端:"io client disconnect"

    ¥client-side: "io client disconnect"

  • 服务器端:"client namespace 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).emit("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
}
});

标志

¥Flags

标志:'volatile'

¥Flag: '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:

  • 插座未连接

    ¥the socket is not connected

  • 底层传输不可写(例如,当 POST 请求已在 HTTP 长轮询模式下运行时)

    ¥the low-level transport is not writable (for example, when a POST request is already running in HTTP long-polling mode)

socket.volatile.emit(/* ... */); // the server may or may not receive it