Skip to content

소켓 새로고침 관리하기

nowChae edited this page Dec 3, 2024 · 1 revision

🚀 도전 목표

게임 진행 시 새로고침을 할 경우 퀴즈가 끊기지 않고 진행할 수 있도록 환경을 구축한다.


💡 핵심 과정 및 결과

이벤트 흐름 및 구조 변경

show quiz 이벤트를 통해서 클라이언트와 마스터는 퀴즈 데이터를 불러온다.


기존 구조

기존

기존 구조의 문제점

  • 참가자의 퀴즈 데이터 수신이 마스터에 의존적입니다. 그래서 참가자가 새로고침 할 경우 참가자는 show quiz 이벤트를 on만 하고 있기 때문에 퀴즈 데이터를 받지 못하고 빈 화면을 보게 됩니다.
  • show quiz 호출 시 currentOrder를 증가시키도록 되어있습니다.
  • 마스터가 새로고침 시 show quiz가 다시 호출되고 currentOrder 또한 증가되어 마스터와 참가자는 바로 다음 문제로 이동하는 문제가 발생합니다.


변경된 구조

변경

변경된 구조

  • start quiz 이벤트가 show quiz 호출과 currentOrder를 증가시키는 trigger가 됩니다.
  • show quiz 를 ack 타입의 이벤트로 변경하고 마스터, 참가자 각각 요청을 보내고 응답을 받는 형식으로 변경되었습니다.

위 방식으로 변경을 했을 경우

  • 참가자의 퀴즈 데이터 수신 여부가 마스터에 의존적이지 않습니다.
  • show quiz 가 currentOrder를 증가시키는 trigger가 아니기 때문에 여러번 show quiz를 호출하여도 동일한 퀴즈 데이터를 받을 수 있습니다.


클라이언트 상태의 영속성 관리 전략: usePersistState 구현

기존 상태 관리의 한계

React 애플리케이션에서 useState를 통한 클라이언트 상태 관리는 페이지 새로고침 시 모든 상태가 초기화되는 한계를 가지고 있었습니다. 특히 퀴즈 진행 도중 실수로 새로고침하거나 브라우저 탭을 닫은 경우, 사용자의 작업 내용이 모두 손실되어 서비스 이용에 큰 불편을 초래할 수 있었습니다.

더 나은 사용자 경험을 위해서는 작업 중인 데이터를 안전하게 보존하고, 예기치 않은 상황에서도 이전 상태로 복원할 수 있는 견고한 상태 관리 전략이 필요했습니다


usePersistState 커스텀 훅 구현

이러한 문제를 해결하기 위해 localStorage를 활용한 영속성 상태 관리 커스텀 훅을 구현했습니다:

이 커스텀 훅은 React의 상태 관리 기능과 브라우저의 localStorage API를 결합하여 페이지 새로고침이나 탭 종료 시에도 상태를 유지할 수 있도록 해줍니다.

유저가 새로고침 또는 탭 종료 시 발생하는 beforeunload 이벤트를 감지하여 유저의 데이터를 저장하고 각 퀴즈 세션이 종료 될 때 마다 localStorage를 비워주는 로직을 추가하였습니다.



Socket.IO와 React Query를 활용한 실시간 상태 관리 최적화

기존 구현의 한계점

기존 실시간 데이터 관리 방식은 Socket.IO를 통해 받은 데이터를 React의 useState로 관리하는 단순한 구조였습니다. 이러한 접근 방식은 다음과 같은 문제점들을 가지고 있었습니다:

  1. 서버 상태와 클라이언트 상태의 불명확한 경계
  2. 실시간 데이터의 캐싱 및 동기화 어려움
  3. 컴포넌트 간 상태 공유를 위한 추가적인 상태 관리 필요
  4. 네트워크 지연이나 오류 상황에 대한 견고한 처리 부재

개선 방안

이러한 문제점들을 해결하기 위해 EmitEventWithAckuseSuspenseQuery를 결합한 새로운 아키텍처를 도입했습니다:


개선된 기능 및 이점

  1. 데이터 일관성 강화
    • React Query의 캐시 메커니즘을 활용하여 서버 상태를 일관되게 관리
    • 실시간 업데이트와 기존 캐시 데이터의 자연스러운 통합
  2. 성능 최적화
    • 불필요한 리렌더링 방지
    • 네트워크 요청 최소화


🔎 개선 사항

  • 에러 핸들링 강화
    • 재연결 메커니즘의 안정성 강화
    • 유저 친화적인 에러 메세지 및 에러 페이지 표시
  • 성능 최적화
    • 데이터 프리페칭을 도입하여 다음 퀴즈에 대한 로드 시간 단축
  • 서버 gateway 메소드들 책임 분리 및 리팩토링
Clone this wiki locally