Socket 实例(客户端)

Socket是与服务器交互的基础类。它继承了 Node.jsEventEmitter的大部分方法,例如 emit, on, onceoff

Bidirectional communication between server and clientBidirectional communication between server and client

除了emittinglistening to事件之外,Socket 实例还有一些可能在您的应用程序中使用的属性:

Socket#id

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

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

  1. // server-side
  2. io.on("connection", (socket) => {
  3. console.log(socket.id); // x8WIv7-mJelg7on_ALbx
  4. });
  5. // client-side
  6. socket.on("connect", () => {
  7. console.log(socket.id); // x8WIv7-mJelg7on_ALbx
  8. });
  9. socket.on("disconnect", () => {
  10. console.log(socket.id); // undefined
  11. });

Socket#connected

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

  1. socket.on("connect", () => {
  2. console.log(socket.connected); // true
  3. });
  4. socket.on("disconnect", () => {
  5. console.log(socket.connected); // false
  6. });

Socket#io

对基础Manager的引用。

  1. socket.on("connect", () => {
  2. const engine = socket.io.engine;
  3. console.log(engine.transport.name); // in most cases, prints "polling"
  4. engine.once("upgrade", () => {
  5. // called when the transport is upgraded (i.e. from HTTP long-polling to WebSocket)
  6. console.log(engine.transport.name); // in most cases, prints "websocket"
  7. });
  8. engine.on("packet", ({ type, data }) => {
  9. // called for each packet received
  10. });
  11. engine.on("packetCreate", ({ type, data }) => {
  12. // called for each packet sent
  13. });
  14. engine.on("drain", () => {
  15. // called when the write buffer is drained
  16. });
  17. engine.on("close", (reason) => {
  18. // called when the underlying connection is closed
  19. });
  20. });

生命周期

Lifecycle diagram

事件

Socket 实例发出三个特殊事件:

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

  1. socket.io.on("reconnect_attempt", () => {
  2. // ...
  3. });
  4. socket.io.on("reconnect", () => {
  5. // ...
  6. });

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

connect

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

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

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

  1. // BAD
  2. socket.on("connect", () => {
  3. socket.on("data", () => { /* ... */ });
  4. });
  5. // GOOD
  6. socket.on("connect", () => {
  7. // ...
  8. });
  9. socket.on("data", () => { /* ... */ });

connect_error

在以下情况下触发此事件:

在第一种情况下,Socket 会在 给定的延迟之后自动尝试重新连接。

在后一种情况下,您需要手动重新连接。您可能需要更新凭据:

  1. // either by directly modifying the `auth` attribute
  2. socket.on("connect_error", () => {
  3. socket.auth.token = "abcd";
  4. socket.connect();
  5. });
  6. // or if the `auth` attribute is a function
  7. const socket = io({
  8. auth: (cb) => {
  9. cb(localStorage.getItem("token"));
  10. }
  11. });
  12. socket.on("connect_error", () => {
  13. setTimeout(() => {
  14. socket.connect();
  15. }, 1000);
  16. });

disconnect

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

  1. socket.on("disconnect", (reason) => {
  2. // ...
  3. });

以下是可能的原因列表:

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

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

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

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

注意:这些事件以及disconnecting, newListenerremoveListener是不应在您的应用程序中使用的特殊事件:

  1. // BAD, will throw an error
  2. socket.emit("disconnect");

完整API

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