[socket.io] Namespaces

김혜지·2020년 12월 1일
0

본문

Namespaces

네임 스페이스는 단일 공유 연결을 통해 애플리케이션의 논리를 분할 할 수있는 통신 채널입니다.

가능한 사용 사례:

  • 권한이 있는 사용자만 액세스 할 수있는 관리 네임 스페이스를 만들려고 하므로 해당 사용자와 관련된 논리가 나머지 애플리케이션과 분리됩니다.
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 namespace
workspaces.use((socket, next) => {
  // ensure the user has access to the workspace
  next();
});

Default namespace

Default namespace를 /라고 부르며 기본적으로 연결되는 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

각 네임 스페이스는 각 Socket 인스턴스를 매개 변수로받는 connection 이벤트를 내 보냅니다.

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

Custom namespaces

사용자 정의 네임 스페이스를 설정하려면 서버 측에서 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/… 입니다.

Namespace middleware

미들웨어는 들어오는 모든 Socket에 대해 실행되는 함수로, 소켓과 다음 등록된 미들웨어로 실행을 선택적으로 연기하는 함수를 매개 변수로 받습니다. Socket.IO 미들웨어는 Express에서 찾을 수 있는 것과 매우 유사합니다.

// registers a middleware for the default namespace
io.use((socket, next) => {
  if (isValid(socket.request)) {
    next();
  } else {
    next(new Error('invalid'));
  }
});

// registers a middleware for a custom namespace
io.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();
});

Handling middleware error

next 메소드가 Error 객체와 함께 호출되면 클라이언트는 connect_error 이벤트를 수신합니다.

import { io } from 'socket.io-client';

const socket = io();

socket.on('connect_error', (err) => {
  console.log(err.message); // prints the message associated with the error, e.g. "thou shall not pass" in the example above
});

Compatibility with Express middleware

대부분의 기존 Express 미들웨어 모듈은 Socket.IO와 호환되어야합니다. 메소드 서명을 일치 시키려면 약간의 래퍼 함수 만 있으면됩니다.

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

요청-응답주기를 종료하고 next()를 호출하지 않는 미들웨어 함수는 작동하지 않습니다.

Example with express-session:

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

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

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

Example with 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'))
  }
});
profile
Developer ( Migrating from https://hyex.github.io/ )

0개의 댓글