채팅을 만들려면 채팅방도 만들어야 하고, 접속한 유저 모두에게 메시지를 발송하는 브로드캐스팅 기능도 필요하고 여러 기능들이 필요하다.

 

socket.io는 웹소켓을 기반으로 서버와 클라이언트의 양방향 통신을 지원하는 라이브러리이다.

 

작업 순서

  1.  프로젝트 생성 및 패키지 설치
  2.  정적 파일 서비스를 위한 main.ts 설정
  3.  socket.io 서버 구동을 위한 게이트웨이 만들기
  4.  클라이언트 측 코드 작성
  5.  테스트

 

1.패키지 설치하기

 

@nestjs/websockets : 클라이언트와 서버를 연결하고 양방향 통신 또는 데이터 전송이 가능하게 해주는 패키지

@nestjs/platform-socket.io  : 웹소켓의 성능향상이나, 실시간 데이터 동기화 같은 웹소켓 프로토콜 기반의 프로그램 작성 시 필수인 패키지

 

2. 정적 파일 서비스 설정

 

NestJS에서는 정적 파일을 불러오는 기능을 제공한다.

 

// 반환형을 NestExpressApplication형으로 지정해 정적 메서드를 사용한다.
const app = await NestFactory.create<NestExpressApplication>(AppModule);
// useStaticAssets : 정적 파일의 경로를 지정
app.useStaticAssets(join(__dirname, '..', 'static'));

 

 

3. 서버 측 작업을 위한 게이트웨이 만들기

 

NestJS에서는 웹소켓을 사용한 통신을 받아주는 클래스를 게이트웨이라한다.

게이트웨이를 만드는 방법은 @WebSocketGateway() 데코레이터를 클래스에 붙이면 된다.

 

@WebSocketServer() : 실제 WebSocket 서버 인스턴스를 참조하게 되서 클라이언트에 메시지 전송, 연결, 관리같은 WebSocket 서버를 제어할 수 있다.

 

@WebSocketGateway() //게이트웨이 설정
export class ChatGateway{
    @WebSocketServer() server: Server; // 웹소켓 인스턴스 생성
    
    @SubscribeMessage('message') //해당 이벤트 구독
    handleMessage(socket: Socket, data: any): void {
        this.server.emit('message', `client-${socket.id.substring(0,4)} : ${data}`,);
    }
}

 

3-1. 게이트웨이를 모듈에 등록하기

 

게이트웨이는 다른 클래스에 주입해서 사용할 수 있는 프로바이더이다.

 

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService, ChatGateway], // 게이트웨이를 프로바이더로 등록, 게이트웨이는 다른 클래스에 주입해서 사용할 수 있는 프로버이더이다.
})

 

 

4. 클라이언트를 위한 index.html 수정

 

웹소켓은 브라우저가 표준 프로토콜이라서 자체적으로 지원을해서 따로 라이브러리를 사용할 필요가 없다.

반면 socket.io는 브라우저에서 따로 지원을 안해줘서 설정을 해줘야한다.

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h2>Simple Nest Chat</h2>
    <div id="chat"></div>
    <input type="text" id="message" placeholder="메시지를 입력해주세요.">
    <button onclick="sendMessage()">전송</button>
</body>
<!-- jquery 로드 -->
<script src="https://code.jquery.com/jquery-3.6.1.slim.js">
</script>
<!-- socket.io 인스턴스 생성 -->
<script src="http://localhost:3000/socket.io/socket.io.js"></script>
<script>
    const socket = io('http://localhost:3000');
    // 전송 버튼을 클릭 시 입력된 글을 message 이벤트로 보냄
    function sendMessage(){
        const message = $('#message').val();
        socket.emit('message', message);
    }
    socket.on('connect', () =>{
        console.log('connected');
    });
    socket.on('message', (message) =>{
        $('#chat').append(`<div>${message}</div>`);
    });
</script>
</html>

 

socket.on('이벤트', '받은 데이터') : emit()에서 발생된 이벤트리스너로 데이터를 받는다

socket.emit('이벤트', '넘겨줄 데이터') : 서버에서 해당 이벤트를 발생시켜 클라이언트 쪽의 해당 이벤트 리스너에게 데이터를 넘겨준다.

 

'WEB > WebSocket' 카테고리의 다른 글

NameSpace 설정하기  (0) 2024.05.10
웹소켓  (0) 2024.05.04

+ Recent posts