프로젝트에서 채팅을 구현한 방법 - 채팅 기능 문서화

2025. 3. 25. 12:42개발

💬 FriendShip의 채팅, 어떻게 설계했을까?

채팅 서비스를 개발하면서 문서화의 중요성을 새삼 느꼈다. 특히 복잡한 시스템을 명확하게 표현하기 위해 시퀀스 다이어그램을 사용했던 경험을 공유하고자 한다.

📌 개요

FriendShip의 채팅 시스템은 STOMP 프로토콜을 기반으로 한 웹소켓을 사용하며, Pub/Sub (Publish-Subscribe) 모델을 따른다. 사용자는 특정 채팅방(chatRoom)의 메시지를 구독하고, 메시지를 발행하여 실시간으로 소통한다.

🍊 Pub/Sub 구조란?

Pub/Sub 구조를 간략하게 뉴스레터 시스템으로 비유하면 이해하기 쉽다:

  • 발행자(Publisher): 뉴스레터를 작성하여 보내는 사람
  • 구독자(Subscriber): 뉴스레터를 받아보는 사람
  • 토픽(Topic): 뉴스레터의 주제 (예: 여행, 요리 등)
  • 메시지 브로커(Message Broker): 우체국처럼 발행자의 메시지를 구독자에게 전달하는 역할

FriendShip에서는 각 채팅방을 토픽으로 설정하여, 메시지가 발행되면 같은 채팅방을 구독한 사용자들이 메시지를 받게 된다.

📨 메시지 전송 및 수신 흐름

채팅 메시지 전송 및 수신 과정은 다음과 같다.

  1. 연결 후 구독
    • 사용자는 웹소켓을 통해 서버에 연결 요청 및 채팅방 구독 요청을 한다.
    • 웹소켓 서버는 이를 메시지 브로커로 전달한다.
  2. 메시지 발행
    • 메시지를 보내려는 사용자는 /app/chat 엔드포인트로 메시지를 발행한다.
    • 서버는 이를 DB에 저장하고 메시지 브로커로 전달한다.
  3. 메시지 수신
    • 메시지 브로커가 구독된 채팅방 토픽에 메시지를 게시하면 사용자는 메시지를 실시간으로 수신한다.

✅ 읽음 처리 기능

채팅 메시지의 읽음 처리는 다음과 같은 시퀀스로 구현했다.

  • 사용자가 메시지를 읽으면 /app/read 엔드포인트로 읽음 확인 정보를 서버에 전송한다.
  • 서버는 해당 메시지의 읽음 상태를 DB에 업데이트하고, 읽음 정보를 채팅방 토픽에 게시한다.
  • 채팅방을 구독 중인 사용자는 메시지 읽음 정보를 실시간으로 확인할 수 있다.

📥 메시지 불러오기 (Stateless)

이 기능은 STOMP 대신 RESTful API를 사용해 메시지를 요청하고 불러오는 과정으로, 주로 채팅방 입장이나 이전 메시지 조회 시 사용된다.

  • 사용자가 RESTful API를 통해 메시지를 요청한다.
  • 서버는 DB에서 메시지를 조회 후 사용자에게 반환한다.

🔔 알림 기능 (FCM 활용)

비접속 사용자에게 메시지 전송 시 FCM을 활용한 푸시 알림이 필요했다.

  • 사용자가 메시지를 서버에 보내면 서버가 비접속 사용자의 FCM 토큰 정보를 활용해 FCM 서버로 알림을 요청한다.
  • FCM 서버가 사용자의 모바일 기기로 알림을 전송한다.
  • 사용자가 알림을 터치하면 채팅방 메시지를 불러오는 과정이 수행된다.

✨ 팀원들과 공유하며 느낀점

이렇게 시퀀스 다이어그램을 활용하여 FriendShip의 채팅 기능을 명확히 정리했다. 팀원들과 공유할 수 있는 명확한 문서 덕분에 개발 초기 단계부터 요구사항을 쉽게 이해하고, 서로 간의 의사소통 오류를 줄일 수 있었다. 또한, 개발 과정에서 수정이 필요하거나 새로운 요구사항이 추가될 때도 다이어그램을 기준으로 명확히 논의할 수 있어 생산성이 높아지는 경험을 했다. 문서화를 통해 개발자 간 소통과 협업이 얼마나 수월해질 수 있는지 경험한 좋은 사례였다.