야외 활동, 이웃과의 소통을 유도하는 땅따먹기 게임
같은 동에서 서로 다른 MBTI 성격을 가진 사람들이 모여 땅따먹기하며 이웃과의 소통을 유도하는 게임입니다.
- 2022.04.29 ~ 2022.06.03
김재혁 | 박용태 | 박재철 | 기우석 | 박세명 |
Frontend | Frontend | Backend | Backend | Backend |
- 카카오를 통한 소셜로그인으로 간단하게 가입할 수 있어요. 이메일 회원가입에서는 중복 가입이 안되도록 중복확인을 눌러야 합니다. 본인의 mbti 를 선택하실 수 있습니다
-
피드 작성하기, 몬스터 처치하기, 타임어택 3가지 종류의 퀘스트가 지도 위에 뿌려져요. 해당 위치 근처에서 퀘스트를 수행할 수 있습니다.
-
몬스터 퀘스트는 몬스터와 직접 게임을 통해서 점수를 올릴 수 있습니다
- 퀘스트를 일정 횟수 수행하면 뱃지를 드려요. 마이페이지에서 자신이 달성한 업적을 퀘스트 타입별로 확인할 수 있어요.
- 특정지역에서 피드를 남겨보세요. 다른 사람이 올린 피드에 댓글로 소통하고 좋아요를 눌러보세요.
-
좀 더 즉각적인 소통을 위해서 채팅방을 이용하세요. 닉네임이 공개되지 않는 익명채팅입니다.
-
좀 더 즉각적인 소통을 위해서 동네 채팅방을 이용하세요.
- 자신이 쌓은 포인트로 랭킹페이지에서 top 10 랭킹을 확인할 수 있습니다.
외부 API 사용에 따른 지연 시간 발생
- 퀘스트를 생성하기 위해 Kakao API, 공공 주소 API 2가지 API 요청을 보내고 응답을 받게 됩니다.
- 지역당 퀘스트 개수만큼의 API 요청을 각각 보내게 됩니다.
- ex. 퀘스트 개수가 50개인 경우 Kakao API 요청 50회, 공공 주소 API 요청 50회 필요
- API 요청을 순서대로 하게 될 경우 API 요청당 1초 정도의 시간이 발생합니다.
- ex. 10개의 요청을 순차적으로 보낼경우 9초 내외의 시간 소요
- API 요청 병렬화
- API 요청을 순차적으로 보내지 않고 Promise.all을 활용하여 병렬적으로 보냅니다.
// src/quests/quests.service.ts const roadAddrs = await Promise.all([ ..addrIndex.map(({ curPage, idx }) => this.getRoadAddress(curPage, address, idx) ), ]);
- 카카오 429 에러 발생에 따른 요청 횟수 제한
- 카카오 API는 한번에 다수의 요청을 보낼 경우 429 Too Many Request 에러를 보냅니다.
- 우선, 제한이 없는 공공 주소 API를 병렬적으로 처리했습니다.
- 카카오 API의 경우에는 요청 횟수에 제한을 두었습니다.
// src/quests/quests.service.ts const limits = 20; // kakaoAPI 429 에러(Too Many Requests) 방지를 위해 요청당 호출수 제한 for (let begin = 0; begin < pageCount; begin += limits) { // 카카오 API 요청 로직 }
- 퀘스트를 사전에 생성 (스케줄링)
- 위와 같은 방법으로도 50여개의 퀘스트를 생성하는데 여전히 4~5초의 시간이 소요되었습니다.
- 퀘스트 최초 생성시에는 부득이하게 발생하는 시간이라고 생각했습니다.
- 다만, 이후의 요청에서는 API 요청을 사용자가 직접하지 않도록 사전에 퀘스트를 생성하였습니다.
- 사용자의 활동이 적은 새벽 1시를 기준으로 스케쥴링하였습니다.
// src/quests/quests.service.ts @Cron('0 0 1 * * *', { timeZone: 'Asia/Seoul' }) async preCreateQuests() { ... }
채팅을 구현하는 중 접속할 때마다 바뀌는 socket의 id를 어떻게 기존 사용자로 인식할 수 있을지를 고민하였습니다.
socket 통신의 경우 클라이언트 측 socket의 id값이 접속할 때마다 바뀌게 됩니다. 이 때 기존의 사용자를 구분해야 합니다.
- userId를 고정값으로 하기 위해서 users라는 테이블을 만들어 userId와 socketId를 저장해 놓습니다.
- socket id가 바뀌어 들어갈 때 users테이블의 userId를 확인하고 socketId를 update하여 기존의 사용자임을 확인합니다.