-
Notifications
You must be signed in to change notification settings - Fork 2
소켓 새로고침 관리하기
게임 진행 시 새로고침을 할 경우 퀴즈가 끊기지 않고 진행할 수 있도록 환경을 구축한다.
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
를 호출하여도 동일한 퀴즈 데이터를 받을 수 있습니다.
기존 상태 관리의 한계
React 애플리케이션에서 useState
를 통한 클라이언트 상태 관리는 페이지 새로고침 시 모든 상태가 초기화되는 한계를 가지고 있었습니다. 특히 퀴즈 진행 도중 실수로 새로고침하거나 브라우저 탭을 닫은 경우, 사용자의 작업 내용이 모두 손실되어 서비스 이용에 큰 불편을 초래할 수 있었습니다.
더 나은 사용자 경험을 위해서는 작업 중인 데이터를 안전하게 보존하고, 예기치 않은 상황에서도 이전 상태로 복원할 수 있는 견고한 상태 관리 전략이 필요했습니다
usePersistState 커스텀 훅 구현
이러한 문제를 해결하기 위해 localStorage
를 활용한 영속성 상태 관리 커스텀 훅을 구현했습니다:
이 커스텀 훅은 React의 상태 관리 기능과 브라우저의 localStorage
API를 결합하여 페이지 새로고침이나 탭 종료 시에도 상태를 유지할 수 있도록 해줍니다.
유저가 새로고침 또는 탭 종료 시 발생하는 beforeunload
이벤트를 감지하여 유저의 데이터를 저장하고 각 퀴즈 세션이 종료 될 때 마다 localStorage
를 비워주는 로직을 추가하였습니다.
기존 구현의 한계점
기존 실시간 데이터 관리 방식은 Socket.IO를 통해 받은 데이터를 React의 useState
로 관리하는 단순한 구조였습니다. 이러한 접근 방식은 다음과 같은 문제점들을 가지고 있었습니다:
- 서버 상태와 클라이언트 상태의 불명확한 경계
- 실시간 데이터의 캐싱 및 동기화 어려움
- 컴포넌트 간 상태 공유를 위한 추가적인 상태 관리 필요
- 네트워크 지연이나 오류 상황에 대한 견고한 처리 부재
개선 방안
이러한 문제점들을 해결하기 위해 EmitEventWithAck
와 useSuspenseQuery
를 결합한 새로운 아키텍처를 도입했습니다:
개선된 기능 및 이점
- 데이터 일관성 강화
- React Query의 캐시 메커니즘을 활용하여 서버 상태를 일관되게 관리
- 실시간 업데이트와 기존 캐시 데이터의 자연스러운 통합
- 성능 최적화
- 불필요한 리렌더링 방지
- 네트워크 요청 최소화
- 에러 핸들링 강화
- 재연결 메커니즘의 안정성 강화
- 유저 친화적인 에러 메세지 및 에러 페이지 표시
- 성능 최적화
- 데이터 프리페칭을 도입하여 다음 퀴즈에 대한 로드 시간 단축
- 서버 gateway 메소드들 책임 분리 및 리팩토링