Передача событий
Существует несколько способов отправки событий между сервером и клиентом.
Для пользователей TypeScript можно указать подсказки типов для событий. Пожалуйста, обратитесь к этой странице.
Основная передача
API Socket.IO вдохновлен EventEmitter из Node.js EventEmitter, что означает, что вы можете передавать события с одной стороны и регистрировать слушателей с другой:
Сервер
io.on("connection", (socket) => {
socket.emit("hello", "world");
});
Клиент
socket.on("hello", (arg) => {
console.log(arg); // world
});
Это также работает в обратном направлении:
Сервер
io.on("connection", (socket) => {
socket.on("hello", (arg) => {
console.log(arg); // world
});
});
Клиент
socket.emit("hello", "world");
Вы можете передавать любое количество аргументов, и поддерживаются все сериализуемые структуры данных, включая двоичные объекты, такие как Buffer или TypedArray.
Сервер
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" });
Примечания:
-
Объекты Date будут преобразованы в (и получены как) их строковое представление, например,
1970-01-01T00:00:00.000Z - Map и Set необходимо сериализовать вручную:
const serializedMap = [...myMap.entries()]; const serializedSet = [...mySet.keys()];
- вы можете использовать метод
toJSON()для настройки сериализации объекта
Пример с классом:
class Hero {
#hp;
constructor() {
this.#hp = 42;
}
toJSON() {
return { hp: this.#hp };
}
}
socket.emit("here's a hero", new Hero());
Подтверждения
События хороши, но в некоторых случаях вам может понадобиться более классический API запросов-ответов. В Socket.IO эта функция называется подтверждениями.
Вы можете добавить обратный вызов в качестве последнего аргумента emit(), и этот обратный вызов будет вызван после того, как другая сторона подтвердит событие:
Сервер
io.on("connection", (socket) => {
socket.on("update item", (arg1, arg2, callback) => {
console.log(arg1); // 1
console.log(arg2); // { name: "updated" }
callback({
status: "ok"
});
});
});
Клиент
socket.emit("update item", "1", { name: "updated" }, (response) => {
console.log(response.status); // ok
});
С таймаутом
Начиная с Socket.IO v4.4.0, вы теперь можете назначить таймаут для каждого отправляемого события:
socket.timeout(5000).emit("my-event", (err) => {
if (err) {
// the other side did not acknowledge the event in the given delay
}
});
Вы также можете использовать как таймаут, так и подтверждение:
socket.timeout(5000).emit("my-event", (err, response) => {
if (err) {
// the other side did not acknowledge the event in the given delay
} else {
console.log(response);
}
});
Летучие события
Летучие события — это события, которые не будут отправлены, если базовое подключение не готово (немного похоже на UDP с точки зрения надёжности).
Это может быть интересно, например, если вам нужно отправить позицию персонажей в онлайн-игре (так как только последние значения полезны).
socket.volatile.emit("hello", "might or might not be received");
Еще один сценарий использования — отбрасывание событий, когда клиент не подключен (по умолчанию события буферизуются до повторного подключения).
Пример:
Сервер
io.on("connection", (socket) => {
console.log("connect");
socket.on("ping", (count) => {
console.log(count);
});
});
Клиент
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/v4/emitting-events