chat realtime 리펙토링 중 생긴 오류 잡기

JeongChan·2025년 7월 1일

Troubleshooting

목록 보기
3/6
post-thumbnail

사용자 정보를 zstand에서 설정한 캐시에 저장된 유저 정보 값을 연결 하는 리펙토링 작업인데

수정하는 단계에서 또 realtime 이 제대로 작동하지 않는 문제가 생겼다.

채팅방에 필요한 렌더링되어어야할 정보때문에 유저(sender)의 정보와 message테이블의 값을 불

러왔을때 값 들을 병합 해야했다.

이때 생긴 문제들의 이유와 해결 방법에 대해 기술해 보았다.


📌개선 사항들



✅ 메시지 병합 전략 개선

기존 코드에서는 실시간으로 메시지를 수신할 때 단순히 userMap을 기준으로 메시지에 sender 정보를 붙이는 방식이었지만, 다음과 같은 문제가 있었다:

  • 실시간으로 수신된 메시지에 이미 같은 message_id가 존재하면 중복 렌더링됨
  • userMap이 최신이 아닐 경우 sender 정보가 누락됨

기존 코드 예시

개선 내용

  • message_id가 이미 존재하는지 확인하고, 중복 방지
  • sender_id 기준으로 기존 messages 배열에서 sender 정보 추출


✅ 구독 종료 조건 명확화

기존 코드에서는 채널 구독 해제를 명확히 하지 않아 다음과 같은 문제가 발생:

  • 창을 전환하거나 개발 서버에서 HMR이 발생하면 WebSocket 재연결 실패 (TIMED_OUT)

기존 코드 예시

개선 내용

  • useEffect cleanup에서 정확히 unsubscribe 실행하여 구독 해제
  • subscriptionRef를 사용해 중복 구독 방지 및 해제 타이밍 관리



✅ subscribeToMessages 함수 변경 이유

기존에는 useMessageSubscription이라는 hook에서 useEffect 내부에서 구독을 처리하고 있었다. 하지만 다음 문제가 발생함:

  • useEffect는 항상 모든 deps 변화마다 채널을 새로 만들고 제거
  • 메시지 초기화 전에 구독이 먼저 실행되면 sender 정보 병합 불가

기존 코드 예시 (hook 기반 구독)

개선 내용

  • subscribeToMessages를 일반 함수로 분리
  • 구독 타이밍을 ChatMessages에서 제어하여, 메시지 fetch 이후 한 번만 실행되도록 함



✅ 주요 변경 요약과 트러블슈팅 설명

이번 리팩토링은 Supabase Realtime을 사용하는 채팅 기능에서 다음과 같은 문제 해결을 목표로 했다

기존 문제들

  • 메시지 수신 시 sender 정보가 누락되거나 병합되지 않음
  • message가 중복 렌더링되거나 실시간 업데이트가 실패함
  • 채널 구독과 해제가 명확하지 않아 WebSocket 타임아웃 및 끊김 발생

해결 전략 요약

  • 구독 시점 제어: 메시지가 모두 불러와지고 나서 구독을 시작하도록 개선
  • 중복 방지 로직: message_id 기준으로 이미 렌더링된 메시지인지 확인
  • sender 정보 병합: userMap 대신 현재 messages 배열에서 sender 정보 추출하여 실시간 메시지 병합
  • 구독 해제 명확화: subscriptionRef를 통해 구독 상태를 추적하고 정확히 해제 처리
  • subscribeToMessages 함수화: useEffect 내부 훅 구조 대신 일반 함수로 분리해 side-effect 제어 명확화

이러한 개선을 통해 다음과 같은 효과를 얻을 수 있었다:

  • 안정적인 실시간 수신 처리
  • 메시지 중복 방지
  • WebSocket 연결 유지 안정화
  • sender 정보 병합 오류 해결
profile
Development Notes

0개의 댓글