Spec-Zone.ru › Socket.IO 3

Отправка событий

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

Основные отправки

API Socket.IO вдохновлен EventEmitter из Node.js EventEmitter, что означает, что вы можете отправлять события с одной стороны и регистрировать слушателей с другой:

// server-side
io.on("connection", (socket) => {
  socket.emit("hello", "world");
});

// client-side
socket.on("hello", (arg) => {
  console.log(arg); // world
});

Это также работает в обратном направлении:

// server-side
io.on("connection", (socket) => {
  socket.on("hello", (arg) => {
    console.log(arg); // world
  });
});

// client-side
socket.emit("hello", "world");

Вы можете отправлять любое количество аргументов, и поддерживаются все сериализуемые структуры данных, включая двоичные объекты, такие как Buffer или TypedArray.

// server-side
io.on("connection", (socket) => {
  socket.emit("hello", 1, "2", { 3: '4', 5: Buffer.from([6]) });
});

// client-side
socket.on("hello", (arg1, arg2, arg3) => {
  console.log(arg1); // 1
  console.log(arg2); // "2"
  console.log(arg3); // { 3: '4', 5: ArrayBuffer (1) [ 6 ] }
});

Не нужно выполнять JSON.stringify() над объектами, так как это будет сделано за вас.

// BAD
socket.emit("hello", JSON.stringify({ name: "John" }));

// GOOD
socket.emit("hello", { name: "John" });

Примечание: Map и Set не сериализуются и должны быть сериализованы вручную:

const serializedMap = [...myMap.entries()];
const serializedSet = [...mySet.keys()];

Подтверждения

События отлично подходят, но в некоторых случаях вам может потребоваться более классический API запроса-ответа. В Socket.IO эта функция называется подтверждениями.

Вы можете добавить обратный вызов в качестве последнего аргумента emit(), и этот обратный вызов будет вызван, как только другая сторона подтвердит событие:

// server-side
io.on("connection", (socket) => {
  socket.on("update item", (arg1, arg2, callback) => {
    console.log(arg1); // 1
    console.log(arg2); // { name: "updated" }
    callback({
      status: "ok"
    });
  });
});

// client-side
socket.emit("update item", "1", { name: "updated" }, (response) => {
  console.log(response.status); // ok
});

Таймауты по умолчанию не поддерживаются, но их довольно просто реализовать:

const withTimeout = (onSuccess, onTimeout, timeout) => {
  let called = false;

  const timer = setTimeout(() => {
    if (called) return;
    called = true;
    onTimeout();
  }, timeout);

  return (...args) => {
    if (called) return;
    called = true;
    clearTimeout(timer);
    onSuccess.apply(this, args);
  }
}

socket.emit("hello", 1, 2, withTimeout(() => {
  console.log("success!");
}, () => {
  console.log("timeout!");
}, 1000));

Летучие события

Летучие события — это события, которые не будут отправлены, если базовое соединение не готово (немного похоже на UDP, с точки зрения надёжности).

Это может быть интересно, например, если вам нужно отправить положение символов в онлайн-игре (поскольку только последние значения полезны).

socket.volatile.emit("hello", "might or might not be received");

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

Пример:

// server-side
io.on("connection", (socket) => {
  console.log("connect");

  socket.on("ping", (count) => {
    console.log(count);
  });
});

// client-side
let count = 0;
setInterval(() => {
  socket.volatile.emit("ping", ++count);
}, 1000);

Если вы перезапустите сервер, вы увидите в консоли:

connect
1
2
3
4
# the server is restarted, the client automatically reconnects
connect
9
10
11

Без флага volatile, вы увидите:

connect
1
2
3
4
# the server is restarted, the client automatically reconnects and sends its buffered events
connect
5
6
7
8
9
10
11

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

Spec-Zone.ru

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