Spec-Zone.ru › Socket.IO 3

Прослушивание событий

Существует несколько способов обработки событий, передаваемых между сервером и клиентом.

Методы EventEmitter

На стороне сервера экземпляр Socket расширяет класс Node.js EventEmitter.

На стороне клиента экземпляр Socket использует эмиттер событий, предоставленный библиотекой component-emitter, которая экспонирует подмножество методов EventEmitter.

socket.on(eventName, listener)

Добавляет функцию listener в конец массива слушателей для события с именем eventName.

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

socket.once(eventName, listener)

Добавляет функцию одноразового listener для события с именем eventName

socket.once("details", (...args) => {
  // ...
});

socket.off(eventName, listener)

Удаляет указанного listener из массива слушателей для события с именем eventName.

const listener = (...args) => {
  console.log(args);
}

socket.on("details", listener);

// and then later...
socket.off("details", listener);

socket.removeAllListeners([eventName])

Удаляет всех слушателей или тех, что относятся к указанному eventName.

// for a specific event
socket.removeAllListeners("details");
// for all events
socket.removeAllListeners();

Слушатели по умолчанию

Начиная с Socket.IO v3, новый API, вдохновлённый библиотекой EventEmitter2, позволяет объявлять слушателей по умолчанию.

Эта функция доступна как на клиенте, так и на сервере.

socket.onAny(listener)

Добавляет слушателя, который будет срабатывать при возникновении любого события.

socket.onAny((eventName, ...args) => {
  // ...
});

socket.prependAny(listener)

Добавляет слушателя, который будет срабатывать при возникновении любого события. Слушатель добавляется в начало массива слушателей.

socket.prependAny((eventName, ...args) => {
  // ...
});

socket.offAny([listener])

Удаляет всех слушателей по умолчанию или заданного слушателя.

const listener = (eventName, ...args) => {
  console.log(eventName, args);
}

socket.onAny(listener);

// and then later...
socket.offAny(listener);

// or all listeners
socket.offAny();

Валидация

Валидация аргументов события выходит за рамки библиотеки Socket.IO.

В экосистеме JS существует множество пакетов, которые покрывают этот случай, среди них:

  • joi
  • ajv
  • validatorjs

Пример с joi и подтверждениями:

const Joi = require("joi");

const userSchema = Joi.object({
  username: Joi.string().max(30).required(),
  email: Joi.string().email().required()
});

io.on("connection", (socket) => {
  socket.on("create user", (payload, callback) => {
    if (typeof callback !== "function") {
      // not an acknowledgement
      return socket.disconnect();
    }
    const { error, value } = userSchema.validate(payload);
    if (error) {
      return callback({
        status: "KO",
        error
      });
    }
    // do something with the value, and then
    callback({
      status: "OK"
    });
  });

});

Обработка ошибок

В настоящее время в библиотеке Socket.IO нет встроенной обработки ошибок, что означает, что вы должны перехватывать любые ошибки, которые могут быть выброшены слушателем.

io.on("connection", (socket) => {
  socket.on("list items", async (callback) => {
    try {
      const items = await findItems();
      callback({
        status: "OK",
        items
      });
    } catch (e) {
      callback({
        status: "NOK"
      });
    }
  });
});

На серверной стороне использование EventEmitter.captureRejections = true (экспериментальное, см. здесь) тоже может быть интересным, в зависимости от вашего случая использования.

require("events").captureRejections = true;

io.on("connection", (socket) => {
  socket.on("list products", async () => {
    const products = await findProducts();
    socket.emit("products", products);
  });

  socket[Symbol.for('nodejs.rejection')] = (err) => {
    socket.emit("error", err);
  };
});

© 2014–2021 Automattic
Licensed under the MIT License.
https://socket.io/docs/v3/listening-to-events

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API