본문 바로가기
내일배움캠프/축구팀 관리 프로젝트

축구팀 관리 프로젝트 - WebSocket 활용한 실시간 채팅 전송 과정

by 코드스니펫 2024. 2. 28.
반응형

축구팀 관리 프로젝트 - WebSocket 활용하여 실시간 채팅 전송 과정

 

pc와 서버 연결되는 이미지

 

축구팀 관리 프로젝트에서 팀원끼리 원활한 소통이 가능하게 하도록 채팅 기능을 넣었습니다. 채팅은 WebSocket을 사용하여 실시간으로 메시지를 송수신하도록 구현했습니다. 본 글에서는 NestJS 프레임워크를 사용하여 채팅 메시지를 송수신하는 과정에서 필요한 코드의 동작 방식과 함께, 이를 구현하는 데 있어서 중요한 몇 가지 개념에 대해 상세히 설명하고자 합니다.

 

 

WebSocket 활용한 실시간 채팅 전송

 

코드 소개 및 동작 방식

우선, 사용자로부터 메시지를 수신하고 처리하는 코드 부분을 살펴보겠습니다.

 

@UseFilters(WsExceptionFilter)
@SubscribeMessage('send_message')
async sendMessage(
    @MessageBody() creatMessagesDto: CreateMessagesDto,
    @ConnectedSocket() socket: Socket,
) {
    // 채팅방 존재 여부 확인
    const chatExists = await this.chatsService.checkIdChatExists(creatMessagesDto.chatId);
    if (!chatExists) {
        throw new WsException({
            statusCode: 404,
            message: `${creatMessagesDto.chatId}번 채팅방은 존재하지 않습니다.`,
        });
    }

    // 메시지 생성 및 전송
    const message = await this.messagesService.createMessage(
        creatMessagesDto,
        socket['userId'],
    );

    socket.to(message.chat.id.toString()).emit('receive_message', {
        id: message.id,
        author: {
            id: message.author.id,
            name: message.author.name,
            email: message.author.email,
        },
        message: message.message,
        createdAt: message.createdAt,
    });
}

 

이 코드는 다음과 같은 프로세스를 따릅니다.

 

채팅방 존재 여부 확인: chatsService.checkIdChatExists 메서드를 통해 전달받은 chatId에 해당하는 채팅방이 존재하는지 확인합니다. 존재하지 않을 경우, 사용자에게 404 에러와 함께 채팅방이 존재하지 않는다는 메시지를 전달합니다.

 

메시지 생성 및 전송: 채팅방이 존재할 경우, messagesService.createMessage 메서드를 사용하여 새로운 메시지를 생성하고, socket.to().emit()을 통해 해당 채팅방의 모든 사용자에게 메시지를 실시간으로 전송합니다.

 

 

주요 문법 설명

@UseFilters(WsExceptionFilter): 이 데코레이터는 WebSocket 통신 과정에서 발생할 수 있는 예외를 처리하기 위해 사용됩니다. 특정 예외가 발생했을 때 클라이언트에게 친절하고 명확한 에러 메시지를 제공하는 역할을 합니다.

 

 

Documentation | NestJS - A progressive Node.js framework

Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with TypeScript and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Rea

docs.nestjs.com

 

@SubscribeMessage와 @MessageBody(): @SubscribeMessage 데코레이터는 클라이언트로부터 특정 이벤트(send_message)를 수신할 때 사용됩니다. @MessageBody()는 해당 이벤트와 함께 전송된 데이터를 메서드의 파라미터로 바인딩할 때 사용되는 데코레이터입니다.

 

socket.to().emit() : socket.to().emit() 메서드는 Socket.IO 라이브러리에서 제공하는 기능 중 하나로, 특정 방(room)에 있는 소켓(사용자)을 대상으로 이벤트를 전송할 때 사용됩니다. 이 메서드를 사용함으로써 서버는 특정 채팅방에 있는 모든 클라이언트에게 메시지를 전송할 수 있으며, 메시지를 발신한 클라이언트를 제외한 다른 클라이언트들만 메시지를 받게 됩니다.

 

 

[Node.js] Socket.io 모듈 (.emit .on)

Socket.io: node.js 기반 실시간 웹 애플리케이션 지원 라이브러리

velog.io

 

 

socket.to().emit() 부가 설명

 

사용 방식

socket.to(roomId).emit(eventName, data) 형식으로 사용됩니다. 여기서 roomId는 메시지를 전송하려는 방의 ID이며, eventName은 클라이언트가 수신 대기하고 있는 이벤트 이름입니다. data는 해당 이벤트와 함께 전송될 데이터입니다.

 

코드 내 사용 예

위에서 제시된 코드에서는 다음과 같이 사용되었습니다.

 

socket.to(message.chat.id.toString()).emit('receive_message', {
    id: message.id,
    author: {
        id: message.author.id,
        name: message.author.name,
        email: message.author.email,
    },
    message: message.message,
    createdAt: message.createdAt,
});

 

이 코드는 새로운 메시지가 생성되었을 때, 해당 메시지 정보를 포함한 receive_message 이벤트를 해당 채팅방의 모든 사용자에게 전송합니다. 여기서 socket.to(message.chat.id.toString())는 메시지가 속한 채팅방의 ID를 문자열로 변환하여 해당 방에 있는 모든 클라이언트를 대상으로 설정하고 있습니다. 그리고 emit('receive_message', {...})는 receive_message 이벤트와 함께 메시지의 상세 정보를 해당 채팅방의 모든 클라이언트에게 전송하도록 합니다.

 

서버와 채팅 관련 이미지

 

특징 및 장점

특정 대상 지정: socket.to().emit() 메서드를 사용하면, 서버가 메시지를 전송하고자 하는 특정 사용자 그룹을 정확하게 지정할 수 있습니다. 이를 통해 불필요한 네트워크 트래픽을 줄이고, 메시지의 전송을 더욱 효율적으로 관리할 수 있습니다.

 

실시간 통신 강화: 이 방식은 실시간 채팅 애플리케이션에서 매우 중요한 역할을 합니다. 사용자가 속한 채팅방에만 메시지를 전송함으로써, 사용자 간의 실시간 소통을 원활하게 지원합니다.

 

socket.to().emit() 메서드의 이러한 특성은 실시간 채팅 애플리케이션뿐만 아니라, 실시간으로 데이터를 공유하거나 업데이트해야 하는 다양한 실시간 애플리케이션 개발에 있어 핵심적인 역할을 합니다. 따라서 이 메서드의 작동 원리와 사용 방법을 정확히 이해하는 것은 NestJS를 사용한 실시간 애플리케이션 개발에 있어 매우 중요합니다.

 

 

끝으로

 

이 글을 통해 NestJS를 활용한 채팅 메시지 송수신 기능의 구현 방법과 이와 관련된 주요 개념 및 기술에 대해 살펴보았습니다. 실시간 통신을 위한 WebSocket의 사용, 데이터 전송을 위한 DTO의 정의, 서비스 레이어의 활용, 그리고 예외 처리를 위한 필터의 사용 등은 모두 중요한 개념들입니다.

 

코드 예제를 통한 설명이 여러분의 이해를 돕고, 이러한 개념들을 이해하고 적절히 활용한다면, 보다 효율적이고 안정적인 채팅 애플리케이션을 개발할 수 있을 것입니다. 본 글이 여러분의 채팅 애플리케이션 개발에 도움이 되기를 바랍니다.

 

▼ 이전 진행한 프로젝트 기록 ▼

 

 

축구팀 관리 프로젝트 - 대규모 트래픽 관리 위해 스케일업, 캐싱 적용

축구팀 관리 프로젝트 - 대규모 트래픽 관리 위해 스케일업, 캐싱 적용 프로젝트를 하며 가장 큰 문제 중 하나는 '트래픽 관리'입니다. 특히 대규모 이벤트나 프로모션 기간에 서비스가 겪는 트

lemonlog.tistory.com

 

 

축구팀 관리 프로젝트 37일차 - 목표 테스트 커버리지 80% 중 56% 달성

축구팀 관리 프로젝트 37일차 - 목표 테스트 커버리지 80% 중 56% 달성 현재 match service 단 테스트 파일 작성중입니다. 커버리지 80%를 목표로 하고 있는 데 아직 56%까지 작업했습니다. match service 테

lemonlog.tistory.com