이번 주차에는 초안 발표가 있었다. 내가 평소 관심 있는 주제, 해보고 싶은 기술을 중심으로 어떤 주제를 하는 게 좋을지 고민해보았다.
내가 평소 관심 있는 주제는 아이돌이고, 구현해보고 싶은 기술은 영상 채팅 / 실시간 채팅이었다.
이렇게 고민하다가 생각난 것이 바로 비대면 팬미팅이었다.
비대면 팬미팅을 할 때 보통 카톡 페이스톡으로 많이 하는데, 소속사에서 일일이 시간을 재면서 걸고 끊고 하는 게 번거롭겠다는 생각이 들었다.
그러면서 "영상 통화를 걸고 끊는 것을 우리가 자동으로 해주면 어떨까?" 라는 생각으로 이어졌다.
마침 우리 조에 아이돌을 좋아하는 친구들도 많았고, 아이돌 라이브를 주제로 프로젝트를 하고 싶어했던 친구도 있었다. 서로의 생각이 모이다보니 재밌는 아이디어들이 엄청 많이 나왔다.
그래서 비대면 팬미팅을 주제로 초안 발표를 했는데, 운영진분들께서 재밌는 주제라는 피드백을 주셔서 이 주제 그대로 진행하게 되었다.
기술 스택은 위와 같이 선정했다.
지난 주에 NextJS를 사용해봤는데, 14 버전으로 업데이트된지가 얼마되지 않아서, 다른 라이브러리와 호환이 안 되는 문제 등이 있었다. 그래서 안전하게 13 버전으로 사용하기로 했다.
그리고 React Query를 사용하기 때문에 상태 관리 라이브러리는 가벼운 것을 사용해도 되겠다 싶었다. 그래서 recoil과 jotai 중 무엇을 사용할까 고민하다가 사용 방법이 좀 더 간단한 jotai를 선택했다.
WebRTC를 구현할 때 어떤 라이브러리를 많이 사용하는지 찾아봤는데, Janus와 OpenVidu를 많이 사용하는 것 같았다. 그런데 Janus의 경우 공식문서 내용이 자세하지 않고, React와 함께 사용한 케이스가 많지 않아서 위험 부담이 크겠다 싶었다. 그래서 WebRTC 라이브러리는 구현 예시가 많은 OpenVidu로 선정했다.
프로젝트 제목은 "돌돌밋"으로 결정했다.
마치 컨테이너 벨트 위를 움직이는 것처럼 돌돌 돌며 나의 아이돌을 만난다는 뜻이다.
먼저 openvidu-tutorials에 있는 코드들은 리액트 옛날 버전의 코드들이어서 요즘의 버전에 맞게 수정하는 작업을 했다.
클래스 기반 컴포넌트의 라이프 사이클 메서드인 componentDidMount
, componentDidUpdate
, componentWillUnmount
들은 useEffect
로 교체해주었다.
우리가 생각했을 때 우리의 핵심 기능은 정해진 시간이 지나면 자동으로 전화를 끊고 다음 아이돌 멤버에게 전화를 걸어주는 것이었다. (카리나와의 2분 통화가 끝나면 자동으로 끊고, 다음 멤버인 윈터에게 자동으로 영상 통화가 연결되는 식으로)
그래서 중간 발표 때까지 이 기능은 꼭 구현하기로 했다.
setInterval
또는 setTimeout
을 사용해서 타이머를 구현하면 되겠지 싶었는데 생각보다 간단하지가 않았다. 그리고 타이머를 구현하는 방식에 따라 시간의 정확도도 달라진다는 사실을 발견했다. 아래 블로그를 참고해서 최대한 정확히 시간을 측정하려고 했다.
Building timer in React? It’s not as simple as you may think!
그리고 setInterval
과 setTimeout
은 비동기 함수가 완료될 때까지 기다려주지 않으므로 유의하자.
OpenVidu 튜토리얼을 보면 사용자가 Join 버튼을 눌렀을 때 영상통화가 연결되게 하는데, 우리가 원하는 기능은 이 방식으로 구현할 수 없었다.
즉, 팬을 대기열에서 기다리고 있게 하다가 앞 사람의 통화가 종료되면 그 때 영상통화가 연결되게 해야 하는데 이걸 어떻게 구현할지 방법을 생각해내는 게 이번 주 중 제일 어려운 부분이었다.
그러다가 OpenVidu API 중 세션에 시그널을 보내는 기능이 있다는 것을 알게 됐다. 즉, 특정 이벤트가 발생하면 해당 세션에 참여하고 있는 커넥션들에게 시그널을 보내는 기능이었다. 이 기능을 사용하면 통화가 종료됐을 때 시그널을 보내서 다음 팬이 참여할 수 있게 할 수 있겠다 싶었다.
그래서 대기열에 들어온 팬은 토큰만 먼저 발급 받아놨다가, 시그널이 왔을 때 그 토큰을 가지고 세션에 connect하도록 기능을 구현했다.
아직 엉성하긴 하지만 아래와 같이 팬들이 차례대로 들어올 수 있는 발판은 마련했다. 어서 속도를 내서 나머지 기능들도 구현해보자!