🛠 기술 스택
FRONT-END
Language
Library
- React
- Axios
- styled-components
- redux-toolkit
- react-cookie
- SockJS
- STOMP
- WebRTC
- framer-motion
Deploy
Cloud Server
BACK-END
Language
Tech Stack
- Spring Boot
- Spring JPA
- Spring security
- JWT
- WebSocket
- STOMP
- WebRTC
Database
Deploy
Cloud Server
💡 기술적 의사 결정
FRONT-END
요구 사항 |
선택지 |
핵심 기술을 선택한 이유 및 근거 |
WebRTC를 이용한 사용자 음성 연결 |
- Mesh(p2p) |
|
- SFU | [Mesh(p2p)]
- 영상 없이 음성통신만 구현하면 되기 때문에 클라이언트의 부하가 심하지 않을 것 이라고 판단함
- Mesh방식의 코드 샘플이 가장 많아 정보를 찾아보기 편했음 |
| 게임 진행 과정에서 서버와 실시간 통신 | - SockJS + STOMP | [SockJS + STOMP]
- 자바스크립트에서 제공하는 웹소켓은 구형 브라우저 에서의 하위호환이 되지 않음
- 따라서 구형 브라우저에서도 작동하게 해주는 SockJS를 우선적으로 고려하였음
- 그러나 서버단에서의 코드가 복잡해지는 문제로 stomp를 사용하였고, 하위호환이 가능하게 하기 위해 stomp에서 사용하는 WebSocket으로 SockJS를 채택하게 됨 |
| 게임 로비에서 실시간 방 정보 조회 | - Polling
- Long Polling
- SSE
- WebSocket | [SSE]
- 많은 데이터를 주고받아야하므로 서버의 부하가 적어야함. 또한 양방향 통신이 아닌 서버에서 클라이언트로의 단방향 통신임
- polling은 구현이 간단하나 실시간으로 반영되지 않음. 만일 실시간으로 반영시키고 싶다면 서버에 짧은 간격으로 요청을 하면 되나 서버의 부하가 심해짐
- Long Polling은 실시간성을 보장받을 수 있으나 구현이 번거로움
- 구현도 간단하고 단방향 통신으로 서버의 부하를 가장 적게 유발하는 SSE가 적합하다 생각되어 선택함 |
| 게임 진행 과정에서 간단한 그림 그리기 | - Canvas API
- WebGL | [Canvas API]
- WebGL은 복잡한 3D 렌더링에 더 선호되고 Canvas API는 일반적으로 2D 렌더링에 더 선호됨
- 간단한 그림을 그리는 기능을 구현하기 위해 WebGL은 지나치게 많은 러닝커브를 필요로함
- 따라서 제로베이스에서 금방 구현할 수 있는 Canvas API를 채택하였음 |
| 전역 상태관리 | - Redux
- MobX
- Recoil | [Redux]
- MobX는 여러개의 store를 가지고있어 상태 변경시 다수의 store가 영향을 받을 수 있고, store의 데이터를 action 발행 없이 업데이트 할 수 있어 구현은 용이할 수 있어도 유지보수의 측면에서 문제를 일으킬 가능성이 있음
- Recoil은 비동기처리와 데이터 캐싱 기능이 있고 보일러플레이트가 없는 등 강점을 가지고 있으나 아직 버전이 낮아 안정성이 떨어짐. 이를 보완하기 위해서 외부 라이브러리를 추가적으로 사용하기도 하나 일정 관계상 새로운 기술을 익히기 촉박했음
- 따라서 가장 많이 사용되어 찾아볼 수 있는 정보가 많은 Redux를 채택하게 되었음 |
| 서버 통신 및 api 호출 | - Axios
- fetch
- Ajax | [Axios]
- 비동기로 HTTP통신을 가능하게 함
- Promise를 객체를 리턴하기 때문에 response를 처리하기도 쉬움
- 폭넓은 브라우저 호환성 |
| CSS | - styled-component
- scss
- tailwind
- 그 외 디자인 컴포넌트 라이브러리(mui, antd, react-toast) | [styled-component]
- 컴포넌트에서 css를 관리하므로 높은 유지보수성
- 컴포넌트에 classname이나 인라인 스타일이 남아 있지 않아서 코드가독성을 높일 수 있음
- props를 통한 동적 스타일링이 가능함 |
BACK-END
요구 사항 |
선택지 |
핵심 기술을 선택한 이유 및 근거 |
WebRTC를 이용한 사용자 음성 연결 |
- Mesh(p2p) |
|
- SFU | [Mesh(p2p)]
- 최대 8명 오디오만 사용하기 때문에 클라이언트의 부하가 크지 않을 것이라고 예측
- 부하가 예측 가능한 상황이라면 성능적 측면에서 Mesh(p2p) 방식이 더 낫다고 판단
- SFU 방식을 선택하게 되면 하나의 서버를 더 관리해야 하므로 현재 프로젝트 규모와 맞지 않음 |
| 게임 진행 과정에서 클라이언트와 실시간 통신 | - SockJS + STOMP | [WebSocket, SockJS, STOMP]
- Websocket을 이용하여 서버와 통신을 했을 때 Handler의 코드가 지나치게 복잡해지는 문제
- 정형화된 타입이 없어 코드 작성중 실수를 하더라도 에러를 throw하지 않고 잘못된 방식으로 작동하는 경우가 있음. 이를 해결하기 위하여 STOMP를 사용
- WebSocket을 지원하지 않는 브라우저를 위해 HTTP Streaming, Long-polling 같은 HTTP 기반의 다른 기술로 전환해 다시 연결을 시도하는 SockJS 사용 |
| 게임 로비에서 실시간 방 정보 조회 | - Polling
- Long Polling
- SSE
- WebSocket | [SSE]
- 서버측에서 클라이언트 측으로 단방향 통신 필요
- 실시간성 뿐 아니라 리소스 측면 고려하여 선택 |
| 그림 이미지 파일 관리 | - Spring Scheduler
- Spring Batch
- Scheduler quartz | [Spring Scheduler]
- 그림을 DB에 저장하여 게임 중 데이터 손실을 방지하고, 동시에 필요없는 데이터를 주기적으로 없애기 위해 스케줄링 필요
- 이벤트 일정에 변동이 없고 이벤트 시 동작하는 로직이 복잡하지 않아서, 프로젝트 규모에 맞게 간단하게 구현 가능한 Spring Scheduler 사용 |
| 비회원 정보 관리 | - MySQL
- Redis
- Memcached | [Redis]
- Redis는 데이터 입력과 삭제가 MySQL에 비해서 10배정도 빠름
- 관계형 데이터베이스와 같이 쿼리 연산을 지원하지 않지만, 대신 데이터의 고속 읽기와 쓰기에 최적화 되어 있음
- Redis는 Memcached 와 달리 단순한 key/value 자료구조 외에도 더 다양한 자료구조를 지원
- Redis 자체적으로 만료 시간 설정 가능 |
Document
Untitled