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

Socket 实例(客户端)

Socket 是与服务器交互的基本类。它继承了 Node.js EventEmitter 的大多数方法,例如 emitononceoff

Bidirectional communication between server and clientBidirectional communication between server and client

除了 发射监听 事件,Socket 实例还有一些属性可能在您的应用程序中很有用

Socket#id

每个新连接都会被分配一个随机的 20 个字符的标识符。

此标识符与服务器端的值同步。

// server-side
io.on("connection", (socket) => {
console.log(socket.id); // x8WIv7-mJelg7on_ALbx
});

// client-side
socket.on("connect", () => {
console.log(socket.id); // x8WIv7-mJelg7on_ALbx
});

socket.on("disconnect", () => {
console.log(socket.id); // undefined
});
注意

请注意,除非启用了 连接状态恢复,否则 id 属性是一个 **短暂的** ID,不应在您的应用程序中使用(或仅用于调试目的),因为

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

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

另请参阅

Socket#connected

此属性描述了套接字当前是否连接到服务器。

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

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

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

生命周期

Lifecycle diagramLifecycle diagram

事件

Socket 实例发出三个特殊事件

提示

从 Socket.IO v3 开始,Socket 实例不再发出与重新连接逻辑相关的任何事件。您可以直接在 Manager 实例上监听这些事件

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

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

更多信息可以在 迁移指南 中找到。

connect

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

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

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

错误 ⚠️

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

正确 👍

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

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

connect_error

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

原因自动重新连接?
无法建立低级连接(暂时性故障)✅ 是
连接被服务器在 中间件函数 中拒绝❌ 否

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

disconnect

  • reason <string>
  • details <DisconnectDetails>

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

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

以下是可能的理由列表

原因描述自动重新连接?
io 服务器断开连接服务器已使用 socket.disconnect() 强制断开套接字连接❌ 否
io 客户端断开连接套接字已使用 socket.disconnect() 手动断开连接❌ 否
ping 超时服务器在 pingInterval + pingTimeout 范围内没有发送 PING✅ 是
传输关闭连接已关闭(例如:用户已断开连接,或网络已从 WiFi 切换到 4G)✅ 是
传输错误连接遇到错误(例如:服务器在 HTTP 长轮询周期中被杀死)✅ 是

socket.active 属性指示套接字是否会在短暂的 随机延迟 后自动尝试重新连接

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

以下事件名称是保留的,不能在您的应用程序中使用

  • connect
  • connect_error
  • disconnect
  • disconnecting
  • newListener
  • removeListener
// BAD, will throw an error
socket.emit("disconnect");

完整 API

可以在 此处 找到 Socket 实例公开的完整 API。