/web15-TadakTadak

타닥타닥 모닥불 앞에서 타닥타닥 코딩하는 서비스 🔥🧑🏻‍💻

Primary LanguageTypeScript

🔥타닥타닥 모닥불 앞에서 타닥타닥 코딩하는 서비스🔥

노션 | 위키 | 백로그 | 갤러리 | 팀 기술 블로그



소개

TadakTadak은 다수의 사용자간 영상, 음성, 채팅을 지원하는 실시간 커뮤니케이션 웹 서비스입니다.
저희 Palette 팀은 개발자들의 아늑한 공간을 만들어 그들의 성장을 돕고 함께 쉬어가는 공간이 될 수 있기를 소망합니다.

실시간으로 서로 학습하는 모습을 공유해요!
음성과 채팅으로 대화를 나눠요!
온라인 불멍과 함께 캠프파이어를 체험해보세요!
직접 호스트가 되어 방을 운영해보세요!
J051_김재훈 J100_배지호 J146_이영범 J198_조한별
img img img img
zaehuun jiho-bae Dev-Beom hanbyeol
Web Backend Web Frontend Web Backend Web Frontend
✅ 모든 구현 기능 리스트

메인 페이지

  • 배치 작업을 통해 만들어진 방문자수 조회
  • 디바운싱을 이용한 실시간 검색
  • 페이지네이션 + 무한스크롤링 적용

마이 페이지

  • 아바타 업로드, 삭제 기능
  • 유저정보 수정 가능
  • 월별 출석 통계
  • 불탄 잔디로 일일 접속 기록 확인

타닥타닥 방

  • 채팅
  • 영상 스트림 전체화면으로 보기
  • 음성 통화
  • 영상 통화
  • 화면 공유
  • 실시간 사용자 상태 반영(추방, 입장, 퇴장)

캠프파이어 방

  • 채팅
  • 음성 통화
  • 모닥불 배경 음악
  • 모닥불 애니메이션
  • 실시간 사용자 상태 반영(추방, 입장, 퇴장)

그리고 숨겨진 이스터에그

인프라 구조

infra

기술 특장점 🛠

🛠 프론트엔드 코드 통일성에 대한 지속적인 고민

협업 및 분업을 원활하게 하기 위해 개발 시 통일성을 부여하고자 많이 고민했어요.

  • TypeScript, eslint, prettier 덕분에 버그를 예방하고 협업 생산성을 높일 수 있었어요.
  • 프로젝트의 매직 넘버는 분리해서 한 곳에서 관리하도록 했어요.
  • 별도의 fetcher 함수를 만들어 API 요청에 대한 처리를 통일시켰어요.
  • 덕분에 응답 다음 작업이나 에러 발생시에도 통일된 작업을 수행할 수 있었어요.
  • CSS 작업시에도 Theme에 선언한 변수를 이용하도록 협의하여 통일성을 부여했어요.
  • 그 외 통일해야 할 부분을 발견하면 즉시 함께 고민하고 실행했어요.
🛠 Agora PaaS의 SDK를 활용한 빠른 실시간 화상 통화 기능

다중 사용자 이용에 적합한 미디어 서버 방식으로 고화질의 화상, 음성화면 공유를 제공해요

  • P2P방식의 Mesh구조는 다중 사용자가 이용하기에 부적합하다고 판단했어요
  • 미디어 서버를 구축하기에는 서버 인프라부족하다고 판단했어요
  • Agora Paas가 제공하는 미디어 서버를 이용하여 실시간 고화질 영상 및 음성을 제공해요
🛠 Socket.IO를 통한 방 별 실시간 기능

Agora SDK에서 영상과 음성 관리에 대한 처리를 담당해줬지만, 추가로 소켓을 도입했어요. 실시간으로 방 별 인원을 관리하고, 입장한 사용자들이 채팅을 통해서도 의사소통을 해야하기 때문이에요. 많은 방들이 존재하고 각 방마다 소켓 통신이 필요하기 때문에, 별도의 소켓 서버를 만들었어요.

  • REST API와 소켓을 통한 검증으로 정해진 인원과 검증된 사용자들이 방에 입장할 수 있어요.
  • 방에 입장하면 참가한 사용자들의 목록을 볼 수 있어요.
  • 음성채팅이 부담스러운 사용자들은 채팅방을 통해 의사소통 할 수 있어요.
🛠 서버 부하 감소를 위한 인프라 구조

소켓 서버를 스케일 아웃을 통해 방·채팅과 관련된 주요 실시간 기능의 성능 저하를 개선하고 싶었어요. 서버 어플리케이션이 늘어남에 따라서 소켓 데이터를 주고받을 수 있는 클러스터링 서버가 필요했어요. 소켓 서버 역할은 데이터 검증과 목적지로의 전달이였어서 데이터를 영구적으로 저장할 필요가 없었어요. 그래서 입력, 삭제 속도가 빠른 인메모리 데이터베이스인 Redis를 선정했어요.

Redis의 Pub/Sub 기능을 사용해 소켓간의 메시지를 클러스터링해요. 또한 하나의 인스턴스에서 도커로 여러개의 애플리케이션을 관리하고있어요. Nginx Reverse Proxy를 통해 다수의 컨테이너를 바인딩해 로드밸런싱을 해줘요.

🛠 NestJS 로 견고한 서버 프로젝트 관리

확장성, 느슨한 결합, 쉬운 유지관리를 위해 아키텍처를 제공해주는 NestJS를 선택했어요.

  • 프로젝트의 구조를 잡아줘 생산성을 향상시켜줘요.
  • 매일 새롭게 바뀐 코드를 봐야하기 때문에 데코레이터로 가독성을 챙겼어요.
  • 제약사항이 늘어났지만 통일성이 생겼어요.
  • 공식문서가 친절하고, 커뮤니티도 활발해요. 도움을 많이 받아 공부해 적용하기 수월했어요.
🛠 통일된 API 규격 및 에러 처리

클라이언트의 효율적인 API 요청 처리를 위해 서버는 일관적인 형태의 API 응답을 제공해줘요.

  • NestJS의 InterceptorFilter를 활용해 모든 요청과 응답을 관리해요.
  • Interceptor는 각 API가 처리한 API 응답을 원하는 형태로 매핑 해줘요.
  • 모든 API 응답은 상태 코드, API 결과, 메세지를 하나의 API 응답 형태로 정해 사용하고 있어요.
  • Filter는 각 API에서 발생한 예외 응답을 원하는 형태로 매핑 해줘요.
  • 모든 예외 응답은 상태 코드, 시간, 예외 발생 경로, 메세지를 하나의 예외 응답 형태로 정해 사용하고 있어요.