안녕하세요!
브릿지 프로젝트에서 메인 기능 중 하나인 채팅 기능에 대한 회고 작성을 시작하려고 합니다.
좋은 경험이 될 것 같아서 시원하게 제가 채팅 구현을 지원했는데,,
지금까지 개발인생에서 구현한 기능 중 가장 난이도도 높고, 그만큼 여러 문제들도 마주쳤습니다.
리스펙하는 향로님의 말씀처럼 몰입의 과정을 기억하기 보단 기록해보려 합니다.
그럼 채팅 기능 회고 시작하겠습니다!
원할한 회고을 위해 간단하게 개발 환경과 채팅 요구사항에 대해 설명 드리겠습니다.
개발 환경
요구사항
모든 기능 개발에서 그렇듯, 다양한 기술과 알고리즘들을 비교하고, 타당한 이유로 적절한 선택을 하여 구현해야 합니다. (개인적으론 개발자란 왜?가 기본 베이스로 깔려 있어야 한다고 생각합니다.)
이러한 이야기를 하는 이유는 ‘채팅’을 막상 구현하려고 하니 정말 막막했고, 폭풍 구글링을 한 결과 명확하게 정해진 방법은 없었습니다.
즉, 제가 비교해보고, 타당한 이유를 바탕으로 적절한 기술 선택을 해야하는 상황이었죠.
이 과정부터 약간 머리가 아파오기 시작했는데요,,어쩌겠습니까 일단 해봐야죠!
일단 채팅이라는 것이 ‘실시간’으로 이루어지기 때문에, 여기서부터 관련 공부를 시작했습니다.
실시간 통신을 위한 기술은 크게 다섯가지가 있습니다.
한가지씩 알아보도록 하겠습니다.
Polling
HTTP 연결에서는 무상태성과 비연결성의 특징을 가지기 때문에 서버가 클라이언트에게 데이터를 보내고 싶어도 일방적으로 보낼 수 없습니다.
즉, 클라이언트로부터 요청을 받아야 응답을 보낼수 있는 것이죠.
이러한 이슈를 보완한 것이 Polling 방식입니다.
핵심은 서버에게 요청을 주기적으로 계속 보내면서 서버가 전달할 데이터가 있다면 응답할 수 있도록 합니다.
단점은 요청을 주기적으로 계속 보내기 때문에 HTTP 오버헤드가 크다는 점입니다.
적합한 서비스 아래와 같습니다.
Long Polling
큰 틀은 Polling 방식과 유사하게 동작하고, 조건 및 설정이 추가된 방식입니다.
즉, 핵심은 Polling 방식과 달리 이벤트가 발생할 때까지 대기 시간을 늘려 요청의 빈도를 줄이는 것입니다.
이론만 봤을 때는 Long Polling 방식이 더 유리해보일 수 있지만, 경우에 따라 Polling 방식보다 서버에 부담을 더 줄 수 있습니다.
적합한 서비스는 아래와 같습니다.
WebSocket
WebSocket은 HTML5 표준 기술로, HTTP 환경에서 하나의 TCP 연결을 맺고 이를통해 실시간 전이중 통신을 가능하게 합니다.
즉, 클라이언트와 서버간의 연결을 지속적으로 유지하고, 양방향으로 통신이 가능합니다.
WebSocket은 요청-응답 개념보단 데이터를 주고 받는 형식입니다.
적합한 서비스는 아래와 같습니다.
SSE (Server Sent Event)
HTML 5 표준 기술로, 서버에서 클라이언트로 단방향 데이터를 전달할 수 있습니다.
장점은 WebSocket과 달리 별도의 프로토콜 구축이 필요하지 않고, Polling처럼 요청을 주기적으로 보내지 않아도 됩니다.
적합한 서비스는 아래와 같습니다.
WebRTC
위의 기술들은 모두 클라이언트-서버 구조로 동작하지만, WebRTC는 P2P 방식으로 통신이 이루어집니다.
또한 별도의 소프트웨어 없이 음성, 영상, 텍스트, 파일 데이터를 브라우저, 단말끼리 주고 받을 수 있고, Latency가 짧은 것이 특징입니다.
적합한 서비스는 아래와 같습니다.
이렇게 여러가지의 실시간 통신 기술에 대해 간략하게 살펴봤습니다.
이제 선택을 해야합니다. 후후
최종적으로 브릿지 프로젝트 채팅 기능의 실시간 통신 기술로 WebSocket 기술을 선택했습니다.
선택의 근거는 생각보다 명확합니다.
여기에 저는 추가로 STOMP 프로토콜을 적용하기로 했습니다.
현재 WebSocket 기술은 텍스트 / 바이너리 두가지 유형의 메세지를 정의하고 있지만, 메세지 내용까지는 정의하지 않습니다.
STOMP는 TCP위에서 작동하는 프로토콜로, 메세지 전송을 효율적으로 하기 위해 등장한 프로토콜입니다.
STOMP는 기본적으로 Pub/Sub 구조를 따르고 있고, 메세지 브로커를 사용할 수 있는 장점이 있습니다.
그렇다면 왜 STOMP를 추가 선택했을까요?
만약 WebSocket으로만 채팅을 구현한다면,
위와 같은 이유로 채팅방마다 세션을 관리해야하는 번거로움이 존재합니다.
하지만 STOMP를 사용한다면,
점에서 큰 장점을 가집니다.
사실 엄밀히 말하자면 WebSocket을 사용한다기보단 틀을 가져간다고 생각하는게 좋을 것 같습니다.
WebSocket으로 HTTP → TCP 전환 후(연결 후), STOMP를 사용하는 구조입니다.
마지막으로 정리해보자면, 아래와 같습니다.
하지만 기본 뼈대가 튼튼해야 무너지지 않기 때문에 꼭 필요한 과정이라고 생각합니다.
그럼 채팅 회고-2 에서 뵙겠습니다.
읽어주셔서 감사합니다. :)