[나만무] 채팅 서비스 설계: REST API & Socket.IO - 정합성을 위한 전체 브로드캐스트 고민

맹쥐·2025년 7월 11일

우리 프로젝트의 채팅 socket 로직을 살펴보자.

💬 채팅 UI 구조

"화면 좌측 하단에 위치한 채팅 버튼"

버튼을 클릭하면 채팅창이 열린다.


이 구조는 픽셀 데이터를 주고받는 socket 통신 방식과 유사한 흐름으로 구현되어 있다.

초기 데이터는 REST API로 처리

마찬가지로 초기데이터는 API로 받는다.

우리는 여러 캔버스를 제공한다.
캔버스 내에 여러 그룹이 존재하고, 사용자는 각 그룹에 속해채팅을 할 수 있다.

처음 채팅창을 열었을 때는 기본 그룹인 '전체' 그룹의 채팅이 선택된다.

이때부터 채팅을 시작할 수는 있으나, 사용자가 이전 채팅 목록을 확인하고 싶어할 것을 고려하여 ..
최근 메시지 50개를 불러오기로 했다.


따라서, 채팅창이 열렸을 때는 다음과 같은 정보가 필요하다.

  • 사용자가 속한 그룹 리스트
  • 기본 그룹인 "전체" 그룹 초기 메시지 50개

이후, 다른 그룹을 이동할 때는

  • 해당 그룹 초기 메세지 50개

이렇게 분리가 된다.
그에 맞춰 API 도 분리하였다.

초기 데이터 [채팅 버튼 클릭 시]

 const response = await apiClient.get('/group/init/chat', {
        params: { canvas_id: canvasId },
      });

이후 그룹별 채팅 초기 데이터

const response = await apiClient.get('group/chat', {
	params: { group_id: groupId, limit },
	});

이후 실시간 메시지는 socket.io

그룹에 속하는 순간 socket을 연결한다.
채팅 소켓 이벤트는

  • joinChat : 채팅방에 참여 -> 서버에서 소켓 룸에 입장시키기 위함
  • sendChat : 메세지 송신
  • onChatMessage : 메세지 수신
  • leavChat : 채팅방 나나기 -> 소켓 룸에서 퇴장하기 위함

이렇게 네개로 구성된다.


메세지 송신을 broadcast로 처리?

내가 보낸 메세지는 오른쪽,
받은 메세지는 왼쪽에 띄우는 것이 일반적이다.

이때 고민이 들었다.

  • 처음엔 내가 보낸 메시지를 UI에 바로 띄울까? 아니면
  • socket의 broadcast로 수신한 뒤 보여줄까?

socket.io 에는 두가지 방식이 있다고 한다.

  1. 보낸 유저를 제외한 나머지에게 broadcast (socket.broadcast.to(room).emit(...))
  2. 보낸 유저도 포함한 전체 broadcast (io.to(room).emit(...))

사실 1번을 선택하면 편하다.
제대로 메세지가 갔는지 확인하지 않고 그냥 UI상에서 띄워주면되니까.
broadcast를 받았을 때 메세지의 주인이 나인지 아닌지 확인하지 않아도 되니까.

이에 대해서는 추후 글에 정리하도록 하겠다.

결론적으로 우리는 정합성을 위해 2번을 선택했다 !


전체 흐름 구조도

profile
이유민

0개의 댓글