'We All Lion' 은 보드게임 '스파이 폴' 을 모티브로 만든 온라인 화상 채팅 보드게임 플랫폼 입니다.
- 사자들 사이에 숨어든 고양이로 디자인 컨셉을 정해 모든 연령대가 접근하기 쉽게 제작했습니다.
- 최소 4명 부터 최대 8명 까지 쉽고 간단한 게임 규칙으로 즐길 수 있습니다.
- 우리끼리?! 지인들과 즐길 수 있도록 비밀방 설정이 가능합니다.
- 실시간 채팅과 캠으로 유저들과 소통하며 온라인으로 지금 당장 게임을 즐겨보세요!
게임설명 & 로그인 페이지 | 로비 페이지 |
---|---|
![]() |
![]() |
유저 프로필 변경 | 방 만들기 |
---|---|
![]() |
![]() |
방 입장 & 대기 페이지 | 게임시작 페이지 |
---|---|
![]() |
![]() |
게임투표 페이지 | 게임종료 페이지 |
---|---|
![]() |
![]() |
게임설명 & 로그인 페이지
- 카카오 소셜로그인 회원가입
- 게임 설명 모달
로비 페이지
- 방 목록 (방 정보 실시간 확인 가능 : 인원, 모드, 방 상태 등)
- 방 만들기 버튼 (공개 & 비공개 / EASY & HARD)
- 로비 전체 채팅
유저 프로필 변경
- 이미지, 유저이름, 게임 승률
- 유저 이름 수정
방 만들기
- 방 만들기 버튼 (공개 & 비공개 / EASY & HARD)
방 입장 & 대기 페이지
- 방 정보 (모드, 인원 등)
- 게임 준비/ 게임 시작
- 방 전체 채팅
- 마이크, 카메라 기능
게임시작 페이지
- 각자 역할 카드 분배 / 제시어 카테고리 & 단어 모달
- 사전 투표 기능
게임투표 페이지
- 스파이 투표하기
- 스파이 정답 제시어 선택
게임종료 페이지
- 스파이 밝히기
- 재시작 및 나가기
프로젝트 구성
├── Dockerfile
├── nodemon.json
├── package-lock.json
├── package.json
├── server.js
├── src
│ ├── app.js
│ ├── chat
│ │ └── chat-socket.js
│ ├── game
│ │ ├── game-provider.js
│ │ ├── game-repo.js
│ │ └── game-socket.js
│ ├── middlewares
│ │ ├── auth-middleware.js
│ │ ├── exception.js
│ │ ├── passport
│ │ │ ├── index.js
│ │ │ └── kakao-stratege.js
│ │ ├── socket-auth-middleware.js
│ │ ├── test.js
│ │ ├── user-error-handler.js
│ │ └── wrap-async-controller.js
│ ├── redis.js
│ ├── rooms
│ │ ├── room-provider.js
│ │ ├── room-repo.js
│ │ └── room-socket.js
│ ├── schemas
│ │ ├── game.js
│ │ ├── index.js
│ │ ├── room.js
│ │ └── user.js
│ ├── socket.js
│ ├── users
│ │ ├── user-controller.js
│ │ ├── user-repo.js
│ │ ├── user-route.js
│ │ ├── user-service.js
│ │ └── util
│ │ ├── jwt.js
│ │ └── user-function.js
│ └── webRTC
│ └── webRTC.js
├── test
│ ├── mockData
│ │ └── user-data.js
│ └── user-test
│ ├── jwt.spec.js
│ ├── user-controller.spec.js
│ ├── user-function.spec.js
│ ├── user-repo.spec.js
│ └── user-service.spec.js
└── 제목 없는 다이어그램.drawio
-
1. Nginx
사용이유
- event-driven의 비동기 구조이므로 채팅 기능이나 RTC기능을 사용 할 때, 동시 접속자 수가 증가를 대비하여 적합한 방식의 웹 서버라고 생각했습니다. 또한 NginX는 이벤트 처리 방식, 비동기식 처리, 논블로킹 방식 처리를 통해 고속으로 처리하는 특징이 있어 사용하게 되었습니다.
- 동시 접속자 수가 많아져도 Apache에 비해 메모리 사용률이 낮고, 처리하는 초 당 요청 수가 앞도적으로 높은 모습을 보여줍니다.
- 메모리를 좀 더 효율적으로 운영할 수 있는 결과를 갖고 오기 때문에 사용하게 되었습니다.
- reverse proxy로 서버 확장에 용이하고 보안적으로 뛰어나기 때문에 사용했습니다.
2. Socket.io
사용이유
- 통상적으로 사용자(서버에 연결된 소켓들)을 세밀하게 관리해야하는 서비스에는 socket.io에 있는 브로드캐스팅을 사용하는게 더 효율적이라고 합니다.
- socket을 이용해서 게임 로직과 같은 복잡한 구조를 갖고 socekt이라는 객체를 활용해서 서비스 내에서 활용하는 부분들을 생각하면 socekt.io가 더 적합하다고 판단했습니다.
3. Redis
사용이유
- 각 게임에 대해 투표 결과 집계나 준비 상태 등 DB에 저장할 필요는 없다고 생각했습니다.
- I/O에 빈번한 간단한 액션들에 대해 가볍게 저장해 둘 DB에 memcached랑 redis 가 후보였습니다. memcached보다 redis가 cloud서비스로 제공이 초기 세팅하기에 더 빨라서 선택하게 됐습니다.
- 간단한 데이터 타입들과 key, value 형식으로 저장할 수 있는 메모리를 사용하는 DB라서 I/O을 다루기에는 redis가 적합하다고 생각했습니다.
- redis를 선택할 때 local과 cloud 두가지 옵션이 있었는데 협업하면서 사용하기에는 아무래도 local보단 cloud가 더 효율적일 것 같다는 생각이 들었습니다.
4. JWT
사용이유
- 카카오에서 발급받은 accessToken을 그대로 사용해도 되지만 카카오의 accessToken 의 유효시간이 11시간으로 굉장히 긴 편이라고 생각했습니다.
- 직접 accessToken을 발급하고 유효시간을 줄여 보안을 조금 더 강화하고자 생각했습니다.
- 세션 방식과 다르게 별도의 인증 저장소가 필요하지 않아 서버와의 커뮤니케이션을 최소한으로 할 수 있어 트래픽에 대한 부담이 적다고 생각이 들었습니다.
5. MongoDB
사용이유
- 프로젝트에서 DB에 저장하는 대상은 유저(전적, 개인정보) / 룸 / 게임 이렇게 세 가지 테이블(콜렉션) 밖에 필요하지 않고, 데이터의 집합 간의 종속성이 많지 않다고 생각했습니다.
- 게임 내에서 실시간으로 변하는 정보나 방 상태의 변화의 경우 일시적인 정보는 Redis를 통해서 저장하기도 하지만, Redis로 모든 정보를 전부 처리할 수는 없기에 DB를 사용해야 하는 경우가 있고, 또 굉장히 자주 DB의 정보를 가져오거나 업데이트해야 하는 상황이 발생한다고 생각이 들었습니다.
- 다른 데이터 집합을 연결시켜서 가져와야 하는 경우가 없다시피하기에 처리 속도가 빠른 NoSQL이 우리의 프로젝트와 더 적합하다고 판단했습니다.
- 소켓을 통해 실시간으로 많은 정보가 생성, 변경되는 서비스이기 때문에 데이터를 빨리 읽어올 수 있으며 수직 및 수평 확장이 가능하다고 생각이 들었습니다.
6. Prettier / ESLint / Babel
사용이유
- prettier 깔끔한 코드와 협업을 위해서 일관성 있는 코드 스타일을 제공해준다 생각하여 사용했습니다.
- eslint 다양한 방식으로 구현할 수 있는 코드 방식을 일관성 있게 구현할 수 있도록 해준다 생각하여 사용했습니다.
- babel Babel을 이용하면 ES6 이상의 최신 문법으로 작성한 자바스크립트 코드를 ES5 이하의 예전 문법으로 작성한 것 처럼 소스 코드 내의 문법의 형태를 변경해주어 다양한 실행환경에서 작동할 수 있게 해준다 생각하여 사용했습니다.
👉 특정 룸으로 채팅메세지 전달 불가 (Socket.io)
👉 docker image로 서버 실행 시 'Javascript heap out of memory' 현상
👉 docker에서 openvidu 서버를 활용한 SFU 방식 테스트 진행 내용
-
BackEnd: WeAllLion-BE
-
FrontEnd: WeAllLion-FE