NestJS-Socket.io(namespace)

효딩딩·2023년 7월 24일
0

네임스페이스

  • 공간이라는 의미를 갖는다.

    예) api로 보면 http 연결방식으로 엔드포인트로 api를 나눠왔다.
    usrs/login, users/signup, chats/:id 등등 이런식으로 공간느낌으로 나뉘게 된다.
    각 공간에는 각각의 api가 세부적으로 나뉘게 된다.

  • 웹소켓에서도 네임스페이스가 존재하고 const socket = io('/') 네임스페이스가 루트로 되어 있어서 다 접속이 가능하다.

  • 네트워크 창을 보면 websocket로 연결한것이 있고 http 연결로 socket.io polling 방식으로 연결한것도 있다.

  • socket.io라는 패키지를 사용해서 거의 모든 브라우저에서 소켓 프로그래밍일 가능하도록 도와주는 라이브러리라고 할수 있다.
    실시간 프로그래밍을 할 수 있는 polling 방식이 전통 방식이고 이것말고도 실시간 데이터 흐름을 처리할수 있는 방식들도 있다. websocket도 한 방법 중에 하나이다.

  • 인터넷 익스프로러 같은 옛날 브라우저와 같은 경우는 웹소켓을 지원하지 않는 경우가 있다. 그래서 웹소켓을 지원하지 않는 브라우저는 폴링방식으로 socket.io와 자동으로 처리할 수 있게 해준다.
    크롬은 웹소켓을 지원하지만 socket.io는 먼저 폴링으로 브라우저한테 전송을 해보고 괜찮다고 생각이 들면 웹소켓으로 소통하게된다.
    이런식으로 socket.io가 소통한다.

  • 이것이 소켓id이다.

만약 네임스페이스를 const socket = io('/sss') 변경하고 connect는 aaa로 해줬다.

44/sss,{message: "Invalid namespace"}
message : "Invalid namespace" // 유효하지 않은 네임스페이스

서버에서 해당하는 네임스페이스를 받을 수 있도록 어떠한 세팅도 안해줘서 이렇게 뜨는것이다.

script.js

const socket = io('/catttings');

chats.geteway.ts

@WebSocketGateway({ namespace: 'catttings' }) // 네임스페이스를 옵션에서 설정가능하다.

  • 하나의 동일한 네임스페이스 안에 해당하는 이벤트들이 명시가 되는것이다. 이것으로 공간을 분리 해준다.

Geteway 생명주기

  • Socket연결에 의한 라이프사이클로 3가지 유용한 인터페이스를 사용할 수 있다.

아래 해당하는 인터페이스를 사용할 때는 규약이다. 해당 클레스에서 반드시 구현해야된다.

1. OnGatewayInit

  • afterInit() 반드시 구현해야하는 implements 이다. (초기화가 되고 바로 실행하는 함수)
  • logger를 보면 constructor 다음으로 afterInit이 실행이 된다.
  • constructor가 먼저 메모리에 올라오고 gateway 가 작동이 될 때 afterInit 이 실행된다.

2. OnGatewayConnection

  • handleConnection() 반드시 구현해야하는 implements이다.
    (소켓이 처음에 연결이 될때 handleConnection이 발동이 된다.)
  • 클라이언트와 연결이 되는 순간 실행이 되는 함수이다. 클라이언트에서 aaa로 연결을 이 되자마자 connect가 떴다.

3. OnGatewayDisconnect

handleDisconnect() 반드시 구현해야하는 implements이다.
(소켓이 연결이 끊길 때 작동이 되는 함수이다.)

순서!

1) constructor 생성자가 가장 먼저 사용된다.
2) afterInit() 이 실행된다.
3) 클라이언트와 연결이 되면 handleConnection() 함수가 실행된다.
connection이 되고 나면 이벤트 발생 후 세션을 나가거나 새로고침을 하거나 사용자가 프로그램 종료를 하게되면
4) 클라이언트와 서버와 연결이 끊기게된다. 그때 handleDisconnect() 함수가 실행한다.

chats.gateway.ts

import { Logger } from '@nestjs/common';
import {
  ConnectedSocket,
  MessageBody,
  OnGatewayConnection,
  OnGatewayDisconnect,
  OnGatewayInit,
  SubscribeMessage,
  WebSocketGateway,
} from '@nestjs/websockets';
import { Socket } from 'socket.io';

@WebSocketGateway({ namespace: 'chattings' }) // 네임스페이스를 옵션에서 설정가능하다.
export class ChatsGateway
  implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect << 
  
{
  private logger = new Logger('chat');
  constructor() {
    this.logger.log('constructor');
  }
  handleDisconnect(@ConnectedSocket() socket: Socket) {
    this.logger.log(`disconnected : ${socket.id} ${socket.nsp.name}`); 
    // aaa 종료 -> disconnected : 4QXh2IZwnaEeduyaAAAD /chattings
    // nsp : namespace
  }

  handleConnection(@ConnectedSocket() socket: Socket) {
    this.logger.log(`connected : ${socket.id} ${socket.nsp.name}`); 
    // aaa 연결 -> connected : vgqhXYVjrgJ8GujUAAAB /chattings
  }

  afterInit() {
    this.logger.log('init'); // gateway 가 실행될 때 가장 먼저 실행되는 함수이다.
  }

  @SubscribeMessage('new_user')
  handleNewUser(
    @MessageBody() username: string,
    @ConnectedSocket() socket: Socket,
  ) {
    console.log(socket.id);

    console.log(username);
    socket.emit('hello_user', `hello ${username}`);
    return 'hello world';
  }
}
profile
어제보다 나은 나의 코딩지식

0개의 댓글