Spec-Zone.ru › Socket.IO 4

Средние сервисы

Функция среднего сервиса — это функция, которая выполняется для каждого входящего соединения.

Функции среднего сервиса могут быть полезны для:

  • ведения журнала
  • аутентификации/авторизации
  • лимитирования скорости

Примечание: эта функция будет выполнена только один раз на соединение (даже если соединение состоит из нескольких HTTP-запросов).

Регистрация среднего сервиса

Функция среднего сервиса имеет доступ к экземпляру Сокета и к следующей зарегистрированной функции среднего сервиса.

io.use((socket, next) => {
  if (isValid(socket.request)) {
    next();
  } else {
    next(new Error("invalid"));
  }
});

Вы можете зарегистрировать несколько функций среднего сервиса, и они будут выполнены последовательно:

io.use((socket, next) => {
  next();
});

io.use((socket, next) => {
  next(new Error("thou shall not pass"));
});

io.use((socket, next) => {
  // not executed, since the previous middleware has returned an error
  next();
});

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

Важное примечание: экземпляр Сокета фактически не подключён, когда выполняется средний сервис, что означает, что ни одно событие disconnect не будет выведено, если соединение в конечном итоге завершится ошибкой.

Например, если клиент вручную закрывает соединение:

// server-side
io.use((socket, next) => {
  setTimeout(() => {
    // next is called after the client disconnection
    next();
  }, 1000);

  socket.on("disconnect", () => {
    // not triggered
  });
});

io.on("connection", (socket) => {
  // not triggered
});

// client-side
const socket = io();
setTimeout(() => {
  socket.disconnect();
}, 500);

Отправка данных авторизации

Клиент может отправить данные авторизации с опцией auth.

// plain object
const socket = io({
  auth: {
    token: "abc"
  }
});

// or with a function
const socket = io({
  auth: (cb) => {
    cb({
      token: "abc"
    });
  }
});

Эти данные авторизации могут быть доступны в объекте установления соединения на стороне сервера:

io.use((socket, next) => {
  const token = socket.handshake.auth.token;
  // ...
});

Обработка ошибок среднего сервиса

Если метод next вызывается с объектом Error, соединение будет отклонено, и клиент получит событие connect_error.

// client-side
socket.on("connect_error", (err) => {
  console.log(err.message); // prints the message associated with the error
});

Вы можете добавить дополнительные сведения в объект Error:

// server-side
io.use((socket, next) => {
  const err = new Error("not authorized");
  err.data = { content: "Please retry later" }; // additional details
  next(err);
});

// client-side
socket.on("connect_error", (err) => {
  console.log(err instanceof Error); // true
  console.log(err.message); // not authorized
  console.log(err.data); // { content: "Please retry later" }
});

Совместимость со средними сервисами Express

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

const wrap = middleware => (socket, next) => middleware(socket.request, {}, next);

Функции среднего сервиса, которые завершают цикл запроса-ответа и не вызывают next(), не будут работать.

Пример с express-session:

const session = require("express-session");

io.use(wrap(session({ secret: "cats" })));

io.on("connection", (socket) => {
  const session = socket.request.session;
});

Пример с Passport:

const session = require("express-session");
const passport = require("passport");

io.use(wrap(session({ secret: "cats" })));
io.use(wrap(passport.initialize()));
io.use(wrap(passport.session()));

io.use((socket, next) => {
  if (socket.request.user) {
    next();
  } else {
    next(new Error("unauthorized"))
  }
});

Полный пример с Passport можно найти здесь.

© 2014–2021 Automattic
Licensed under the MIT License.
https://socket.io/docs/v4/middlewares

Spec-Zone.ru

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