본문 바로가기
블로그 이미지

방문해 주셔서 감사합니다! 항상 행복하세요!

  
   - 문의사항은 메일 또는 댓글로 언제든 연락주세요.
   - "해줘","답 내놔" 같은 질문은 답변드리지 않습니다.
   - 메일주소 : lts06069@naver.com


Node.js/Nestjs (Nest.js)

Nestjs 프레임워크 서버(websocket) -12

야근없는 행복한 삶을 위해 ~
by 마샤와 곰 2022. 9. 7.

#Websocket (웹소켓)

express 프레임워크처럼 nest.js 에서도 웹소켓을 간단하게 설정하여 사용 할 수 있습니다.

자주 사용되는 socket.io 라는 프레임워크를 한번 사용하여 보았습니다.

2개 모듈을 설치하여 줍니다.

npm install @nestjs/websockets 
npm install @nestjs/platform-socket.io

 

nestjs에서의 웹소켓을 담당하는 기능은 "컨트롤러(Controller)" 라는 이름으로 불리우기 보다는 "어뎁터(Adaptor)" 라는 이름을 주로 사용하는 것 같아서 여기서도 마찬가지로 어뎁터라는 이름으로 기능을 만들어 보았습니다.

먼저 전체코드를 살펴 봅니다.

* 파일이름 : 웹소켓어뎁터.ts

import { WebSocketGateway, WebSocketServer, SubscribeMessage, OnGatewayConnection, OnGatewayDisconnect } from '@nestjs/websockets';
import { Socket, Server } from 'socket.io';

@WebSocketGateway(3131, {
  cors: { origin: '*' }
})
export class 웹소켓어뎁터 implements OnGatewayConnection, OnGatewayDisconnect {
  @WebSocketServer()
  server: Server;

  users: number = 0;

  //OnGatewayConnection를 오버라이딩
  async handleConnection() {
    this.users++;  //사용자 증가
    this.server.emit('users', this.users);
    console.log(this.users);
  }

  //OnGatewayDisconnect를 오버라이딩
  async handleDisconnect() {
    this.users--;  //사용자 감소
    this.server.emit('users', this.users);
    console.log(this.users);
  }

  @SubscribeMessage('chat')
  async onChat(client : Socket, message) { 
    console.log(client.rooms)  //현재 클라이언트의 방
    console.log(message)    //메시지
    client.broadcast.emit('chat', message);  //전체에게 방송함
  }
}

 

1) OnGatewayConnection, OnGatewayDisconnect  인터페이스 : 접속 및 종료 이벤트 감지 기능

해당 클래스는 OnGatewayConnection 인터페이스와 OnGatewayDisconnect 인터페이스를 상속받아서 구현되었습니다.

OnGatewayConnection 인터페이스는 handleConnection 함수를 오버라이딩해서 사용 할 수 있습니다.

  //OnGatewayConnection를 오버라이딩
  async handleConnection() {
  
    //누군가 접속하면 동작 합니다...
    
  }

 

OnGatewayDisconnect 인터페이스는 handleDisconnect 함수를 오버라이딩 할 수 있습니다.

  //OnGatewayDisconnect를 오버라이딩
  async handleDisconnect() {
  
    //누군가 접속이 끊어지면 동작 합니다...
    
  }

 

2) @WebSocketGateway 데코레이터 : 웹소켓 동작을 부여하는 기능

클래스 상단에 사용된 @WebSocketGateway 데코레이터는 해당 클래스가 웹소켓 리스너(서버, 어뎁터)로서의 역할을 할 수 있도록 기능을 부여하여 줍니다.

앞에 숫자 3131값은 포트 3131번에서 동작하라는 옵션이며, 뒤에 cors 는 cross-origin옵션에서의 모두 허용을 의미 합니다.

3131포트에서 동작하게 해 줍니다.

 

3) @SubscribeMessage 데코레이터 : 서버에서 메시지를 수신하는 기능

함수 onChat에 붙어있는 @SubscribeMessage 데코레이터는 chat 이라는 주소값으로 요청이 들어오면 동작하도록 하는 기능을 담당 합니다.    예) 127.0.0.1:3131/chat

client 변수는 메시지를 보낸 웹소켓 객체를 반환하며, message는 전송한 메시지 입니다.

 

4) @WebSocketServer 데코레이터

server 변수에 적용된 @WebSocketServer 데코레이터는 현재 동작중인 웹소켓서버 객체를 의미 합니다.

해당 객체에는 붙어있는 클라이언트의 값을 가져올 수 있으며, 이벤트를 붙이거나 전체 방송, 만들어진 방 등에 대해서 동작하게 할 수 있습니다.

 

이제 동작을 위해서 클라이언트 페이지를 만들어 줍니다.

메인 파일에 html 페이지 접근을 위한 ststic 설정을 해 줍니다.

* 파일이름 : main.ts

import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule);
  app.useStaticAssets("html파일이있는경로");
  await app.listen(3000);
}
bootstrap();

 

다음으로 샘플 코드를 만들어 줍니다.

방에 접속한 뒤에 고정적인 랜덤값을 전송해 주는 간단한 기능을 붙여주도록 합니다.

* 파일이름 : index.html

<html>
<head>
    <script src="https://cdn.socket.io/4.3.2/socket.io.min.js"
        integrity="sha384-KAZ4DtjNhLChOB/hxXuKqhMLYvx3b5MlT55xPEiNmREKRzeEm+RVPlTnAn0ajQNs"
        crossorigin="anonymous"></script>
    <script>
        function makeid(length) {
            var result = '';
            var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
            var charactersLength = characters.length;
            for (var i = 0; i < length; i++) {
                result += characters.charAt(Math.floor(Math.random() * charactersLength));
            }
            return result;
        }
        const id = makeid(5);
        const socket = io('http://localhost:3131');
        socket.on('users', function (data) {
            console.log('Connected', data);
        });
        socket.on('chat', function (data) {
            console.log('event', data);
        });
        function send() {
            socket.emit('chat', { test: 'test', data : id });
        }
    </script>
</head>

<body>
    <button onclick="send()">send test</button>

</body>

</html>

 

해당 페이지는 3000번 포트로 접근해야하며, 웹소켓 서버는 3131포트로 접근을 해야 합니다.

이제 동작시켜 보도록 합니다!

잘되는군요!

 

어렵지 않게 서로 메시지를 주고받는 모습을 볼 수있습니다!

위 내용에 사용된 전체 코드는 아래 제 깃허브에서 받아볼 수 있습니다.

https://github.com/TaeSeungRyu/NestProject/tree/main/step11

 

GitHub - TaeSeungRyu/NestProject: Nestjs 프로젝트

Nestjs 프로젝트. Contribute to TaeSeungRyu/NestProject development by creating an account on GitHub.

github.com

 

공부하면 할 수록 재미있고 즐거운 nestjs!!!
다음 포스팅에서는 데이터베이스 연결에 대해서 살펴보겠습니다.
궁금한점 또는 틀린부분은 언제든 연락 주세요!

 

반응형
* 위 에니메이션은 Html의 캔버스(canvas)기반으로 동작하는 기능 입니다. Html 캔버스 튜토리얼 도 한번 살펴보세요~ :)
* 직접 만든 Html 캔버스 애니메이션 도 한번 살펴보세요~ :)

댓글