BooQuiz 프로젝트 4주차 발표

안녕하세요. 저희는 실시간으로 부스트 캠퍼 300분을 모시고 퀴즈를 진행할 수 있는 BooQuiz 프로젝트를 진행 중인 웹 08 하하팀입니다. 저희가 한 번씩 발표를 꼭 하자라는 그라운드 룰에 따라서 제가 이번 주 발표를 맡아서 진행하겠습니다.

저희 기술 스택은 TypeScript, WebSocket을 공통으로 사용하고 프론트엔드는 React, Shadcn UI, Tailwind, 백엔드는 NestJS를 사용하고 있습니다.

이번 주 핵심 작업 내용

먼저 모각글 활동입니다. 저희가 그라운드룰로 주말 토요일 오전에 모여서 글을 적는 시간을 가지고 있습니다. 이번주는 주로 프론트엔드에서 테스트 코드와 관련된 내용, 도커 샌드박스 환경 구축, 그리고 웹소켓에 관련된 내용들이 주로 있습니다. 세부적인 내용은 링크를 참고하시면 좋을 것 같습니다.

**[WebSocket 통신 난독화](<https://www.notion.so/WebSocket-72c27e4fb24f4473be05cc2238b1781a?pvs=21>)**  

[[FE] Vitest 테스트 코드 작성하기](<https://www.notion.so/FE-Vitest-140f1897cdf5801587c5cb35829becda?pvs=21>) 

[프론트엔드에서 테스트 코드를 작성해야 되는 이유](<https://www.notion.so/a0aaa7cc860445a49e000a58f4c11e57?pvs=21>) 

[도커를 이용한 테스트 환경 구축](<https://www.notion.so/a4e628e3a2664f10bc5ccd3915e02436?pvs=21>) 

[웹소켓 + 리버스 프록시(엔진엑스)](<https://www.notion.so/2325bd00d5b04718b295857ff2dbfcef?pvs=21>) 

[WsAdapter 커스터마이징](<https://www.notion.so/WsAdapter-b702ace55d4c46be9c9bb97df1c50652?pvs=21>)

1. 인프라 테스트 서버 환경 세팅

저희가 CI/CD 환경을 구축한 후에 실제 배포 과정에서 여러 이슈들이 발생했었는데요. 특히 백엔드와 프론트를 합치는 과정에서 안전하게 검증을 할 수 있는 환경이 필요했습니다. 그래서 도커 기반의 테스트 환경을 구축했고, 실제 환경과 동일한 구성으로 테스트를 할 수 있도록 구성해두었습니다.

도커 외에도 여러 가지 대안을 검토했는데요:

하지만 현재 프로젝트 규모에서는 구현하는 데 부담이 크게 되어서, 샌드박스와 스테이징 환경의 장점을 모두 가진 도커 기반의 통합 환경을 선택하게 되었습니다.

실제로 이렇게 구성했던 환경의 실효성은 어제 4주차 배포를 하는 과정에서 바로 테스트를 하면서 에러를 해결할 수 있어서 입증이 되었습니다.

2. WebSocket 사용자 식별 문제 처리

생각보다 웹소켓이 자주 끊기는 현상이 있었습니다. 이게 사실 가장 큰 문제가 연결될 때마다 소켓 정보가 바뀌어서 동일한 사용자를 식별 못하는 문제였는데요. 예를 들어서 퀴즈를 진행하다가 사용자의 연결이 끊겼다 복구되면 시스템은 이전 사용자와 새로 연결된 사용자를 다른 사용자로 인식하게 되는 문제가 있었습니다.

기본적으로 저희는 Socket.IO가 아닌 WebSocket을 기본으로 사용을 하고 있어서 따로 방 관리나 브로드캐스팅 같은 기능을 지원하지 않아서 직접 사용자 식별을 구현해야 했고, 여러 방안을 검토하다가 세션 기반의 사용자 식별 방식을 채택해서 진행 중에 있습니다.

구체적인 구현은 쿠키에서 세션 아이디를 추출하고 웹소켓 객체에 저장하는 방식으로, 재연결이 발생하더라도 동일한 세션 아이디를 통해서 사용자를 올바르게 식별할 수 있도록 해두었습니다. 실제로 적용했을 때 연결이 불안정한 상태에서도 퀴즈 진행 상태가 안정적으로 유지되는 걸 확인할 수 있었고, 향후에는 이걸 좀 더 발전시켜서 상세 동기화나 일시적인 끊김에 대해서도 처리를 하려고 합니다.

3. 퀴즈존 구현 관련 도전 과제

4주차 목표가 다수 인원이 퀴즈 진행에 접속을 해서 퀴즈를 진행할 수 있는 것이 목표인데요. 이를 진행하기 위해서 여러 가지 기술적인 도전 과제들이 있었습니다.

첫 번째로는 아무래도 Socket.IO가 아닌 WebSocket을 사용하다 보니까 방을 관리할 수 있는 기본 기능이 없었고, 이것이 다수의 사용자가 참여하는 퀴즈존을 구현하는 데 큰 과제로 작용했습니다. 서버 내부에 Plays 저장소를 새로 구현을 해서 각 퀴즈존별로 참여자들의 WebSocket 연결을 추적하고 사용자 상태를 실시간으로 관리할 수 있도록 했고요.