개발일지

Nest.js socket.io

index.ys 2023. 11. 20. 22:05

클라이언트 코드

  • socket.emit 메서드로 클라이언트에서 입력된 메세지를 서버로 전송함
  • socket.emit 으로 전송한 메세지는 서버에서 emit메서드로 다시 클라이언트로 반환함 이때 반환된 메세지는 socket.on메서드에서 처리함, 두번쨰 인자로 메세지를 전달받으면 handleNewMessage함수를 호출하여 전달된 메세지를 처리하는 추가 코드 실행
//socket.js
const socket = io("http://localhost:3000/chat")

const message = document.getElementById('message');
const messages = document.getElementById('messages');

//메세지를 전송하는 함수 socket.emit 메서드를 이용해 'message' 라는 이벤트를 서버로 전송
const handleSubmitNewMessage = () => {
  socket.emit('message', { data: message.value })
}

//서버에서 'message' 이벤트가 발생하면 클라이언트에서 message를 수신하고
//메세지를 처리함 handleNewMessage 함수에서 전달받은 메세지를 처리함
socket.on('message', ({ data }) => {
  handleNewMessage(data);
})

//새로운 메세지를 받았을때 호출되는 함수
//새로운 메세지를 처리하고 DOM에 추가하는 역할
const handleNewMessage = (message) => {
  messages.appendChild(buildNewMessage(message));
}

const buildNewMessage = (message) => {
  const li = document.createElement("li");
  li.appendChild(document.createTextNode(message))
  return li;
}

 

서버 코드

  • app.module에 ChatGateway 모듈 추가
//app.moudule.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ChatGateway } from './chat.gateway';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService, ChatGateway],
})
export class AppModule {}
  • localhost:3000/chat 경로에 메세지가 발생했을떄 이벤트를 수신하는 경로를 지정함 ({ namespace : 'chat' })
  • @subcribeMesssage 데코레이터에서 'message' 이벤트가 발생하면 처리하는 코드 실행
  • handleMessage 함수를 호출함, 첫번쨰 인자로 입력된 message에는 클라이언트에서 입력한 메세지가 전달됨
  • this.server.emit메서드를 실행하여 클라이언트에서 emit메서드로 전달된 메세지를 서버에서 받고 다시 클라이언트의 socket.on 메서드로 전달함
//chat.gateway.ts
import {
  MessageBody,
  SubscribeMessage,
  WebSocketGateway,
  WebSocketServer,
} from '@nestjs/websockets';

//ChatGateway 클래스를 WebSocket 게이트웨이로 표시, 클라이언트간 통신
@WebSocketGateway({ namespace: 'chat' })
export class ChatGateway {
  @WebSocketServer()
  server;

  //handleMessage 메서드에 적용되어 해당 메서드가 클라이언트에서
  //전송한 'message' 이벤트에 대한 메세지를 수신함
  @SubscribeMessage('message')
  //@MessageBody데코레이터는 WebSocket 메시지 페이로드에서
  //메세지 내용을 추출
  handleMessage(@MessageBody() message: string): void {
    //emit 메서드는 전달받은 메세지를 모든 클라이언트에게 전송함\
    //emit 메서드의 첫번째 인자는 수신한 이벤트이름, 두번째 인자는 실제로 전송됨 메세지 입력값
    this.server.emit('message', message);
  }
}