Spec-Zone.ru › Socket.IO 2

Пространства имён

Пространство имён — это канал связи, который позволяет разделить логику вашего приложения на отдельном общем соединении.

Namespace diagram

Возможные варианты использования:

  • вы хотите создать пространство имён администратора, к которому имеют доступ только авторизованные пользователи, чтобы логика, связанная с этими пользователями, была отделена от остальной части приложения
const adminNamespace = io.of('/admin');adminNamespace.use((socket, next) => {  // ensure the user has sufficient rights  next();});adminNamespace.on('connection', socket => {  socket.on('delete user', () => {    // ...  });});
  • ваше приложение имеет нескольких арендаторов, поэтому вы хотите динамически создать по одному пространству имён на каждого арендатора
const workspaces = io.of(/^\/\w+$/);workspaces.on('connection', socket => {  const workspace = socket.nsp;  workspace.emit('hello');});// this middleware will be assigned to each namespaceworkspaces.use((socket, next) => {  // ensure the user has access to the workspace  next();});

Пространство имён по умолчанию

Мы называем пространство имён по умолчанию / и оно является тем, к которому клиенты Socket.IO подключаются по умолчанию, и к которому сервер прослушивает по умолчанию.

Это пространство имён идентифицируется по io.sockets или просто io:

// the following two will emit to all the sockets connected to `/`io.sockets.emit('hi', 'everyone');io.emit('hi', 'everyone'); // short form

Каждое пространство имён излучает событие connection, которое получает каждый экземпляр Socket в качестве параметра

io.on('connection', socket => {  socket.on('disconnect', () => {});});

Пользовательские пространства имён

Для настройки пользовательского пространства имён можно вызвать функцию of на стороне сервера:

const nsp = io.of('/my-namespace');nsp.on('connection', socket => {  console.log('someone connected');});nsp.emit('hi', 'everyone!');

На стороне клиента вы указываете клиенту Socket.IO подключиться к этому пространству имён:

const socket = io('/my-namespace');

Важное примечание: Пространство имён — это деталь реализации протокола Socket.IO, и не связано с фактическим URL базового транспорта, который по умолчанию /socket.io/….

Прослойки пространства имён

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

// registers a middleware for the default namespaceio.use((socket, next) => {  if (isValid(socket.request)) {    next();  } else {    next(new Error('invalid'));  }});// registers a middleware for a custom namespaceio.of('/admin').use(async (socket, next) => {  const user = await fetchUser(socket.handshake.query);  if (user.isAdmin) {    socket.user = user;    next();  } else {    next(new Error('forbidden'));  }});

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

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 вызывается с объектом Error, клиент получит событие error.

import io from 'socket.io-client';const socket = io();socket.on('error', (reason) => {  console.log(reason); // prints the message associated with the error, e.g. "thou shall not pass" in the example above});

Совместимость с прослойками 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–2020 Automattic
Licensed under the MIT License.
https://socket.io/docs/v2/namespaces

Spec-Zone.ru

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