4주간의 프로젝트를 진행하며 (1 / 2)

김도연
5 min readSep 14, 2018

--

슈뢰딩거의 고양이

4주간 진행된 슈뢰딩거의 고양이 프로젝트에서 일어난 이슈들을 이야기하는 포스팅입니다. 슈뢰딩거의 고양이는 react native로 제작된 위치기반 랜덤 채팅 서비스를 제공하는 앱입니다. 앱스토어와 플레이스토어에서 다운로드 하실 수 있습니다

코드스테이츠 부트캠프의 마지막 4주 프로젝트에 대한 짧은 기록 1번째

프로젝트의 제안자는 나였다.

프로젝트는 지하철을 타고 출근하던 어느 날, 심심하고 무료해서 누군가와 대화를 하고 싶다는 생각에서 시작되었다. 슈뢰딩거의 고양이는 사용자의 위치를 기반으로 랜덤 채팅방을 생성하여 주변 사용자들과 대화를 나눌 수 있는 서비스를 제공하는 앱이다.

저는 시원하기도 하고 출근하기도 해야해서…

부트캠프 수강생들 앞에서 나의 프로젝트를 제안했고 프론트엔드 2명, 백엔드 2명으로 4주간의, 부트캠프의 마지막 프로젝트가 시작되었다.

프로젝트를 본격적으로 시작하기 전에, 프로덕트 오너이자 PM으로 초기 기획의도와 설계에 대해 이야기하고 팀원들과 합의하고 진행하고 싶었다. 내가 발견하지 못했거나, 부족한 부분들을 팀원들이 발견하고 채워줄 수 있을 것이라 생각했기 때문이다.

확실히 팀원들은 각자 본인이 생각하고 있는 슈뢰딩거의 고양이에 대해 이야기했다. 누군가는 지도에서 표현되는 다이나믹한 채팅방을 생각하고, 누구는 수 많은 사람들이 함께 들어가는 채널같은 채팅방을 생각했다.

수 많은 미팅이 진행되고 각자의 의견과 서비스에 대한 격차가 점점 좁혀지면서 점점 구체적인 슈뢰딩거의 고양이가 머릿속으로 그려지기 시작했다.

프로토타이핑

구체적으로 시작적으로 볼 수 있는 것이 있으면 팀원들이 작업하는데 도움이 될 것 같아 balsamiq으로 프로토타이핑을 했다.

채팅방 입장 초기 프로토타입
채팅방 초기 프로토타입

프로토타이핑을 하고 가장 좋았던 점은 모든 팀원이 동일한 프로덕트의 모습과 앱의 플로우와 기능을 공유하고 있다는 것이었다. 서로 같은 말을 하지만 머릿속으로 다른 프로덕트를 그리고 있다면 나중에 합쳐질때 엉뚱한 결과가 나올 수 있기 때문이다. 그리고 함께 프론트를 진행하는 팀원뿐 아니라, 백엔드를 담당하는 팀원들도 프로토타이핑을 보고우리가 요청했던 api 외에도 내부적으로 고민하거나 더 추가하면 좋겠다는 api를 제안했다.

프로토타입을 기반으로 척척 만들어지는 것들을 바라보며 우린 잠시 이런 생각을 했다.

당연히 아니지.

그렇게 1주가 지나자 새로운 문제가 수면위로 떠올랐다. 아니, 그건 문제의 시작일 뿐이었다.

2주차가 되자 프로토타입이 구현되어 얼추 채팅 앱의 모습을 갖추었다. 하지만 프로토타입만으로는 극복할 수 없는 일들이 발생했다.

우리는 4주안에 리액트 네이티브로 두개의 플랫폼(iOS / Android)에서 실제 서비스 되는 앱을 런칭해야하는 것이 목표였기에 최대한 빠른 속도로 작업을 시작했다. 문제는 살을 붙여나가면 버텨줄 튼튼한 토대가 없었다는 것이었다.

서버는 개복치처럼 터져나갔다. 각 클라이언트 속의 타이머들은 모두 다른 시간이 흐르고 있었다. 지정된 시간이 되면 사라져야 할 방은 사라지지 않고 영원히 존재했다.

채팅방의 경우의 수를 제대로 고려하지 않은 탓에 서버는 시도때도 없이 터졌다. 때로는정체를 알 수 없는 일들이 벌어지며 우리를 공포에 몰아넣었다.

지옥에서 온 소켓들. 끝도 없이 접속을 시도한다.

하지만 백엔드 팀원들은 포기하지 않고 해답을 찾기 위해 노력했다. 그들은 서버가 터지는 모든 케이스를 찾고, 우리는 서버에게 정확한 시점에 더 구체적인 요청을 보내기 위해 코드를 수정했다. 예를 들면 채팅이 종료되는 것을 알리는 leaveRoom 이벤트에 timeOut을 추가해 시간종료로 인한 채팅 이벤트와 의도적으로 채팅을 종료하는 경우를 나누었다.

서버가 어느정도 안정화 되고 클라이언트의 문제를 해결하기 시작했다.

채팅방의 시간이 클라이언트 마다 다른 경우를 보정하기 위해 남은 시간에서 1초씩 줄여가는 방식에서 최초 생성 시간을 서버에서 받아와 매초 마다 현재 시간을 빼서 정확히 남은 시간을 보여주는 방식으로 바꾸었다.

타이머 컴포넌트도 container / presentational component로 나누어 behavior와 presentational 로직을 분리했다.

appState에 이벤트 리스너를 달아서 background와 active 상태를 구분하여 백그라운드 상태에서 돌아왔을 때 시간을 보정하던 것도 자연스럽게 더 이상 이벤트 리스너 없이도 해결할 수 있었다.

2번째 포스팅에서 계속!

--

--

김도연
김도연

No responses yet