Экземпляр сервера
Экземпляр сервера (часто называемый io в примерах кода) имеет несколько атрибутов, которые могут быть полезны в вашем приложении.
Он также наследует все методы основного пространства имён основного пространства имён, такие как namespace.use() (см. здесь) или namespace.allSockets().
Server#engine
Ссылка на базовый сервер Engine.IO.
Он может использоваться для получения количества подключённых клиентов:
const count = io.engine.clientsCount;
// may or may not be similar to the count of Socket instances in the main namespace, depending on your usage
const count2 = io.of("/").sockets.size;
Или для генерации пользовательского идентификатора сессии (параметр запроса sid) :
const uuid = require("uuid");
io.engine.generateId = (req) => {
return uuid.v4(); // must be unique across all Socket.IO servers
}
Начиная с socket.io@4.1.0, сервер Engine.IO испускает три специальных события:
-
initial_headers: будет испускаться незадолго до записи заголовков ответа первого HTTP-запроса сессии (рукопожатия), позволяя настроить их.
io.engine.on("initial_headers", (headers, req) => {
headers["test"] = "123";
headers["set-cookie"] = "mycookie=456";
});
-
headers: будет испускаться незадолго до записи заголовков ответа каждого HTTP-запроса сессии (включая обновление WebSocket), позволяя настроить их.
io.engine.on("headers", (headers, req) => {
headers["test"] = "789";
});
-
connection_error: будет испускаться при аномальном закрытии соединения.
io.engine.on("connection_error", (err) => {
console.log(err.req); // the request object
console.log(err.code); // the error code, for example 1
console.log(err.message); // the error message, for example "Session ID unknown"
console.log(err.context); // some additional error context
});
Вот список возможных кодов ошибок:
| Код | Сообщение |
|---|---|
| 0 | "Неизвестный транспорт" |
| 1 | "Неизвестный идентификатор сессии" |
| 2 | "Неправильный метод рукопожатия" |
| 3 | "Неправильный запрос" |
| 4 | "Запрещено" |
| 5 | "Неподдерживаемая версия протокола" |
Утилитарные методы
Некоторые утилитарные методы были добавлены в Socket.IO v4.0.0 для управления экземплярами Socket и их комнатами:
-
socketsJoin: заставляет соответствующие экземпляры сокетов присоединиться к указанным комнатам -
socketsLeave: заставляет соответствующие экземпляры сокетов покинуть указанные комнаты -
disconnectSockets: заставляет соответствующие экземпляры сокетов отключиться -
fetchSockets: возвращает соответствующие экземпляры сокетов
Метод serverSideEmit был добавлен в Socket.IO v4.1.0.
Эти методы имеют те же семантические характеристики, что и широковещательная передача, и применяются те же фильтры:
io.of("/admin").in("room1").except("room2").local.disconnectSockets();
Что заставляет все экземпляры сокетов пространства имён "admin"
- в комнате "room1" (
in("room1")илиto("room1")) - за исключением экземпляров в "room2" (
except("room2")) - и только на текущем сервере Socket.IO (
local)
отключиться.
Обратите внимание, что они также совместимы с адаптером Redis (начиная с socket.io-redis@6.1.0), что означает, что они будут работать на разных серверах Socket.IO.
socketsJoin
Этот метод заставляет соответствующие экземпляры Socket присоединиться к указанным комнатам:
// make all Socket instances join the "room1" room
io.socketsJoin("room1");
// make all Socket instances in the "room1" room join the "room2" and "room3" rooms
io.in("room1").socketsJoin(["room2", "room3"]);
// make all Socket instances in the "room1" room of the "admin" namespace join the "room2" room
io.of("/admin").in("room1").socketsJoin("room2");
// this also works with a single socket ID
io.in(theSocketId).socketsJoin("room1");
socketsLeave
Этот метод заставляет соответствующие экземпляры Socket покинуть указанные комнаты:
// make all Socket instances leave the "room1" room
io.socketsLeave("room1");
// make all Socket instances in the "room1" room leave the "room2" and "room3" rooms
io.in("room1").socketsLeave(["room2", "room3"]);
// make all Socket instances in the "room1" room of the "admin" namespace leave the "room2" room
io.of("/admin").in("room1").socketsLeave("room2");
// this also works with a single socket ID
io.in(theSocketId).socketsLeave("room1");
disconnectSockets
Этот метод заставляет соответствующие экземпляры Socket отключиться:
// make all Socket instances disconnect
io.disconnectSockets();
// make all Socket instances in the "room1" room disconnect (and discard the low-level connection)
io.in("room1").disconnectSockets(true);
// make all Socket instances in the "room1" room of the "admin" namespace disconnect
io.of("/admin").in("room1").disconnectSockets();
// this also works with a single socket ID
io.of("/admin").in(theSocketId).disconnectSockets();
fetchSockets
Этот метод возвращает соответствующие экземпляры Socket:
// return all Socket instances of the main namespace
const sockets = await io.fetchSockets();
// return all Socket instances in the "room1" room of the main namespace
const sockets = await io.in("room1").fetchSockets();
// return all Socket instances in the "room1" room of the "admin" namespace
const sockets = await io.of("/admin").in("room1").fetchSockets();
// this also works with a single socket ID
const sockets = await io.in(theSocketId).fetchSockets();
Переменная sockets в примере выше — это массив объектов, экспонирующих подмножество обычного класса Socket:
for (const socket of sockets) {
console.log(socket.id);
console.log(socket.handshake);
console.log(socket.rooms);
console.log(socket.data);
socket.emit(/* ... */);
socket.join(/* ... */);
socket.leave(/* ... */);
socket.disconnect(/* ... */);
}
Атрибут data — произвольный объект, который может использоваться для обмена информацией между серверами Socket.IO:
// server A
io.on("connection", (socket) => {
socket.data.username = "alice";
});
// server B
const sockets = await io.fetchSockets();
console.log(sockets[0].data.username); // "alice"
serverSideEmit
Этот метод позволяет испускать события на другие серверы Socket.IO кластера в настройке с несколькими серверами здесь.
Синтаксис:
io.serverSideEmit("hello", "world");
И на стороне получения:
io.on("hello", (arg1) => {
console.log(arg1); // prints "world"
});
Поддерживаются и подтверждения:
// server A
io.serverSideEmit("ping", (err, responses) => {
console.log(responses[0]); // prints "pong"
});
// server B
io.on("ping", (cb) => {
cb("pong");
});
Примечания:
- строки
connection,connectиnew_namespaceзарезервированы и не могут быть использованы в вашем приложении. - Вы можете отправлять любое количество аргументов, но двоичные структуры в настоящее время не поддерживаются (массив аргументов будет
JSON.stringify-ом)
Пример:
io.serverSideEmit("hello", "world", 1, "2", { 3: "4" });
- Обработчик подтверждения может быть вызван с ошибкой, если другие серверы Socket.IO не ответят в течение заданного времени.
io.serverSideEmit("ping", (err, responses) => {
if (err) {
// at least one Socket.IO server has not responded
// the 'responses' array contains all the responses already received though
} else {
// success! the 'responses' array contains one object per other Socket.IO server in the cluster
}
});
События
Экземпляр сервера испускает одно событие (точнее, два, но connect является псевдонимом для connection):
connection
Это событие срабатывает при новом подключении. Первый аргумент — экземпляр Socket.
io.on("connection", (socket) => {
// ...
});
Полный API
Полный API, предоставляемый экземпляром сервера, доступен здесь.
© 2014–2021 Automattic
Licensed under the MIT License.
https://socket.io/docs/v4/server-instance