평범한 일상 속에서 보드게임을 한다고 가정 해볼까요?
친구, 지인, 혹은 매번 하던 사람들과 게임을 하게 되겠죠.
그러면 그들이 어떤 방식으로 게임을 할지, 이 판이 어떻게 진행될지 눈에 쉽게 보입니다.
그러므로 즐거움의 한계를 맞이할 수 있죠. 또한 보드게임 진행에 가장 어려운 부분은 아무래도 함께 할 사람을 모으는 것인데요.
그렇다면 오직 보드게임을 좋아한다는 공통점 아래 자율적으로 모인, 생판 모르는 사람들과 보다 더 신나게 게임을 즐겨볼까요?
재미의 상한선을 깨 보는거죠! 이러한 기대를 안고 보드게임 파티원 매칭을 도와줄 프로젝트를 지금, 시작합니다!
로그인 페이지 |
메인 페이지 |
상세 페이지 |
신청 페이지 |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
채팅 페이지 |
아바타 페이지 |
랭킹 페이지 |
마이 페이지 |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
회원가입
- 기본 회원 가입과 소셜을 통한 회원가입
메인 페이지
- 보드 게임 파티원을 모집할 수 있는 게시글 작성 및 확인
필터링, 검색, 북마크
- 유저가 위치, 시간, 인원을 통해 원하는 게시글 필터링
- 인상 깊었거나 생각나는 제목 혹은 유저 닉네임을 검색
- 마음이 가거나 하고 싶은 게임을 찜해둘수 있는 북마크
위치기반
- 자기가 있는 위치에서 가장 가까운 장소가 적힌 게시글 정렬
커스텀 아바타
- 게시글을 달아서 얻은 포인트로 원하는 아바타로 커스텀
랭킹시스템
- 지금까지 얻은 포인트를 가지고 순위 측정
MySQL -> MongoDB
도입 : 기존에 사용해왔던 부분이라 MySQL default처럼 사용해도 큰 문제가 없을거 같아 이용했습니다.
문제상황 : 긴 프로젝트를 진행하면서 스키마를 추가해야하는 상황이 생기고, 그로 인해 테이블도 자주 변경하는 현상이 일어나, 유연하지 않은 관계형 데이터베이스를 사용하는데에 어려움이 생겼습니다. 그리고 매칭시스템을 하기 위해서 실시간 채팅을 도입해야했고, 채팅의 특성상 처리해야 할 데이터의 양이 빠르게 증가하기 때문에 수평 확장을 통해 더 많은 탄력성을 제공하는 noSQL 도입의 필요성을 더 크게 느꼈습니다.
의견 결정 : 많은 데이터를 저장해야하고, 스키마에 대한 정의가 없어서 그때 그때 변경할수있고, 최적화된 Key-Value기법으로 저장하기에 응답,처리속도가 좋은 MongoDB로 결정했습니다.
Access Token, Refresh Token
도입 : access Token만 있을 경우, 계속 사용하기 때문에 시간을 늘려야하는데, 이때, 탈취가되면 그 긴 시간동안 마음대로 사용할 수 있기때문, Refresh Token 도입
문제상황 : Refresh Token을 DB에 저장하고 Access Token이 만료가 됐을 때, DB에 Refresh Token이 살아있는 걸 확인한 후 자동적으로 Access Token생성해주다보니, 여전히 Access Token이 만료되더라도 탈취가 되면 자동적으로 생성해서 주기 때문에 Refresh Token을 도입한 이유가 없습니다.
의견 결정 : 로그인 시 Refresh Token을 프론트한테 넘겨줘서 만료 시에 그 Refresh Token과 DB에 있는게 맞는지 체크 후, Refresh Token 만료인지 아닌지 다 체크한 후에 Access Token을 보내주도록 설정했습니다.
Socket.io 연결
도입 : 채팅방 기능을 위해서 websocket을 위한 구현보다 모든 브라우저에 적용이 되면서 기능 자체가 포함되어있는 socket.io를 선택하게 되었습니다.
문제상황 : http에서 아무 문제 없던 부분이 nginx를 통해 연결하고나니, websocket connection failed라는 반복적인 오류를 계속해서 등장하였고, 1대1 채팅은 괜찮았지만 여러명이 들어와서 채팅을 경우 순간적으로 백과 프론트 연결이 끊어지면서 더 많은 failed 문자가 나왔습니다.
의견 결정 : Nginx 안에서도 websocket을 가능하게 열어주는 시스템이 존재하였습니다. Nginx 기본 설정으로는 1.0으로 되어있는데 커넥션을 유지하기 위해서는 version을 1.1로 바꿔줘야하고, 홉 사이간의 연결, 즉 두 서버 사이에만 영향이 있고, 다른 영향을 안주면서 커넥션을 유지하고, 새 커넥션을 안열기 위해 hop-by-hop 헤더를 넣어서 오류가 안뜨게 해줬습니다.
포인트 해킹
도입 : 아바타서비스가 있기때문에 이 서비스를 위해서 포인트 제도를 도입
문제상황 : 프론트 측에서 포인트 차감을 계산을 다 하고나서 유저 변경하는 api에 쏴주는 형식으로 설정을 해두었으나, devTool을 통해 api경로만 알면 Thunder, Postman 등으로 포인트를 임의적으로 수정이 가능해지는 상황이 발생해 버렸습니다.
의견 결정 : 프론트 측에서 보내주지말고, 백에서 자체적으로 아바타 번경 시 값이 자동 차감되도록하고, 유저변경 사항에는 포인트 자체를 변경 못하도록 막았습니다.
useState의 비동기적 작동으로 인한 이슈
도입 : 위치기반서비스를 위해서, 모임의 좌표와 유저의 현재위치 좌표값 사이의 거리를 다시 배열에 넣어주어야함.
문제상황 : map함수를 돌린 뒤, 각각의 리턴값에서 거리를 다시 배열에 넣어주어야 하는데, 가장 마지막으로 계산된 거리만 배열에 들어가는 상황이 발생함.
의견 결정 : useState는 비동기적으로 작동하며, batch형태로 16ms마다 일괄처리하는 방식임을 알게되었다. 그리고 useState를 동기적으로 처리하기위해서 setState의 인자로 콜백함수를 넣어, 동기적으로 처리하여 정상으로 배열에 넣어줄 수 있게되었다.
카카오맵 API 렌더링 이슈
도입 : 파티모임의 장소를 지도로 보여주는 기능
문제상황 : 카카오맵API를 사용하는 과정에서 useEffect내 함수를 작동시키려 했으나, 기존 useEffect 내의 콜백함수는 모든 element가 반환된 후 작동하기 때문에, 참조할 수 없다는 오류가 발생함.
의견 결정 : 로딩을 통하여, 시간 차이를 두어 함수가 정상적으로 작동할 수 있게되었다.
파티모임 시간 표시 방식
도입 : 파티모임의 시간을 보여주는 기능
문제상황 : 시간을 밀리초로 다루지 않고, 더 가독성이 좋은 방법을 사용하였으면 좋겠음
의견 결정 : 시간을 표현하는 방식이 여러가지인데 밀리초로 변경하지 않아도 시간의 선후 관계를 정할 수 있다는 것을 알게 되었고, 시간 객체를 시분 단위로 set해서 조절해서 원하는 시간을 표현함.
팀원 | 주특기 | 맡은 파트 |
---|---|---|
김지용 | FE(VL) |
회원가입, 기본 및 소셜(카톡)로그인, 마이페이지, 아바타, 채팅방 |
김수진 | FE |
메인, 필터, 게시글작성, 소셜(네이버)로그인, 검색페이지 |
정원지 | FE |
상세페이지, 댓글, 블랙리스트, 소셜(구글)로그인, 랭킹페이지 |
조민수 | BE(L) |
회원가입, 기본 및 소셜(카톡,구글)로그인, 마이페이지, 채팅방, 스웨거 |
서수형 | BE |
게시글, 랭킹, 북마크, 페이지 무한스크롤, 참가자 목록 추가 및 제거 , 강퇴시스템, 스웨거 |
백이현 | BE |
댓글, 게시글 검색 및 필터링, 소셜(네이버)로그인, 스웨거 |
장수현 | DESIGN |
웹페이지 전체적인 디자인 |
팀원 | 블로그 | 깃허브 |
---|---|---|
김지용 | 김지용의 블로그 | 김지용의 깃허브 |
김수진 | 김수진의 블로그 | 김수진의 깃허브 |
정원지 | 정원지의 블로그 | 정원지의 깃허브 |
조민수 | 조민수의 블로그 | 조민수의 깃허브 |
서수형 | 서수형의 블로그 | 서수형의 깃허브 |
백이현 | 백이현의 블로그 | 백이현의 깃허브 |