[socket.io] dynamic namespace 에서 room의 모든 socket에 이벤트 전송하기

김혜지·2020년 12월 14일
0

Dynamic namespace

동적으로 생성되는 namespace를 말한다.

const namespaces = io.of(/^\/namespace\/\w+/)

클라이언트에서 아래 예시 중 어떠한 케이스로도 소켓 연결이 가능하다.

const socket = io(`${baseURL}/namespace/1`)
const socket = io(`${baseURL}/namespace/a`)
const socket = io(`${baseURL}/namespace/helloworld`)

Trouble

하나의 namespace에 속한 room 중 channelId을 이름으로 하는 room의 모든 소켓에 이벤트를 전송하려고 했다.

const namespace = io.of(/^\/namespace\/\w+/)

namespace.on('connection', (socket: Socket) => {
  socket.on(
      'CREATE_THREAD',
      async (channelId) => {
        namespace.to(channelId.toString()).emit('CREATE_THREAD')
      },
    )
})

그러나 아무리 시도해봐도, 모든 namespace의 모든 room에 이벤트가 전송되는 문제가 발생했다.

Shooting

공식 문서를 자세히 보자

Dynamic namespace는 server API 중 server.of(nsp)를 사용하여 생성된다. 공식 문서의 server.of(nsp)는 정말 짧은 내용과 간단한 예시만이 나와있다. 하지만 답은 이 곳에 있었다.

const dynamicNsp = io.of(/^\/dynamic-\d+$/).on('connection', (socket) => {
  const newNamespace = socket.nsp; // newNamespace.name === '/dynamic-101'

  // broadcast to all clients in the given sub-namespace
  newNamespace.emit('hello');
});

// client-side
const socket = io('/dynamic-101');

// broadcast to all clients in each sub-namespace
dynamicNsp.emit('hello');

// use a middleware for each sub-namespace
dynamicNsp.use((socket, next) => { /* ... */ });

문제는 바로 이것이다.

const newNamespace = socket.nsp;

Dynamic namespace에서는 io.of(nsp)가 반환한 namespace를 바로 사용할 수 없고, socket.nsp를 통해 꺼내 사용해야만 한다. 따라서 아래와 같이 코드를 변경했다.

const namespaces = io.of(/^\/namespace\/\w+/) // 변경

namespaces.on('connection', (socket: Socket) => { // 변경
  const namespace = socket.nsp // 추가
  socket.on(
      'CREATE_THREAD',
      async (channelId) => {
        namespace.to(channelId.toString()).emit('CREATE_THREAD')
      },
    )
})

아직 남은 의문

namespace가 알맞지 않았다는 것은 알았지만, 그렇다해도 뒤에 to(...)가 있는데 왜 모든 채널에 전송된 것인지는 모르겠다.

profile
Developer ( Migrating from https://hyex.github.io/ )

0개의 댓글