제가 이번에 프로젝트에서 실시간 통신 파트를 맡게 되어서 웹소켓과 WebRTC를 사용 했었는데 마침 실시간 통신하는 여러 방법이 있어서 정리 해봤습니다.
최신 실시간 웹 애플리케이션에서는 서버에서 클라이언트로 이벤트를 전송하는 기능이 필수적입니다.
최초의 기술적 해결책인 롱폴링
, 양방향 통신을 위한 더 강력한 해결책인 웹소켓
, 서버에서 클라이언트로의 단방향 통신을 제공하는 Server-Sent Events
, HTTP/3 프로토콜을 활용한 Web Transport
, 특정 상황에서 자주 사용되는 WebRTC
까지 여러 방법이 있는데 위 기술들을 심층적으로 살펴보고 성능을 비교하며, 장점과 한계를 나타내어 실시간 웹 애플리케이션을 만들 때 더 나은 결정을 할 수 있게 도와줄 것 입니다
롱 폴링이란?
롱 폴링은 HTTP를 통해 브라우저에서 실시간에 가까운
서버-클라이언트 통신을 구현하기 위한 초기 기술적 해결책입니다.
- 작동 원리:
- 클라이언트가 서버에 HTTP 요청을 보냅니다.
- 서버는 새로운 데이터가 있을 때까지 연결을 유지합니다(보통 설정된 타임아웃 시간까지).
- 새로운 데이터가 있으면 서버가 응답을 보내고 연결이 종료됩니다.
- 클라이언트는 응답을 받는 즉시 새로운 연결을 시작합니다.
- 장점:
- 일반적인 HTTP 통신을 사용하여 구현이 간단합니다.
- 방화벽이나 프록시 서버의 제약 없이 사용할 수 있습니다.
- 전통적인 폴링보다 서버 부하와 네트워크 트래픽이 감소합니다.
- 단점:
- 다수의 클라이언트 연결 시 서버 리소스 사용량이 증가합니다.
- 실시간성이 웹소켓 등 다른 기술들에 비해 떨어집니다.
- 연결 재설정 과정에서 데이터 지연이나 손실이 발생할 수 있습니다.
- 자바스크립트 클라이언트의 롱 폴링
function longPoll() {
fetch('http://example.com/poll')
.then(response => response.json())
.then(data => {
console.log("Received data:", data);
longPoll();
})
.catch(error => {
setTimeout(longPoll, 10000);
});
}
longPoll();
웹소켓이란?
웹소켓은 브라우저와 서버 사이에 지속적인 양방향 통신 채널을 제공하는 기술입니다.
일단 연결이 되면 클라이언트와 서버는 추가적인 HTTP 요청 없이 자유롭게 데이터를 주고받을 수 있습니다.
Server-Sent Events란?
Server-Sent Events는 서버에서 클라이언트로 실시간 업데이트를 전송하기 위한 웹 표준 기술입니다.
일반 HTTP 연결을 통해 이벤트 스트리밍을 구현하며, 서버에서 클라이언트로의 단방향 통신에 특화되어 있습니다.
- 작동 방식:
1. 클라이언트가 EventSource 객체를 통해 서버에 연결을 요청합니다.
2. 서버는 text/event-stream 형식으로 응답하며, 연결을 유지합니다. (서버 측에서는 반드시 Content-Type
헤더가 text/event-stream
으로 설정되어 있어야 합니다.)
3. 서버는 새로운 데이터가 있을 때마다 이벤트 형태로 클라이언트에 전송합니다.
4. 연결이 끊어지면 클라이언트가 자동으로 재연결을 시도합니다.
- 주요 특징:
- 단방향 통신만 지원 (서버 → 클라이언트)
- 내장된 자동 재연결 메커니즘
- 이벤트 ID를 통한 메시지 추적 가능
- 서버는 각 메시지에
id
필드를 포함시켜 전송할 수 있고 연결이 끊겼다가 다시 연결될 때 클라이언트가 마지막으로 받은 이벤트 ID를 서버에 전송합니다. 서버는 이 id를 기반으로 놓친 메시지들을 다시 전송할 수 있어, 데이터 손실을 방지할 수 있습니다.
- 이벤트 타입 구분 지원
- 자바스크립트 클라이언트의 SSE
const evtSource = new EventSource("https://example.com/events");
evtSource.onmessage = event => {
console.log('got message: ' + event.data);
};
evtSource.addEventListener('userUpdate', (e) => {
});
evtSource.addEventListener('newsAlert', (e) => {
});
WebTransport란?
WebTransport는 웹 클라이언트와 서버 간의 현대적인 통신을 위해 설계된 차세대 API입니다.
이 기술은 HTTP/3의 QUIC 프로토콜(UDP)을 기반으로 하며, 기존 통신 방식들의 한계를 극복하기 위해 개발되었습니다.
- 주요 특징과 기능:
- 다중 데이터 스트림 지원
- 여러 독립적인 데이터 스트림을 동시에 처리할 수 있습니다
- 하나의 스트림에 문제가 생겨도 다른 스트림은 영향받지 않습니다
- 유연한 데이터 전송 모드
- 신뢰성 있는 전송의 경우:
- 패킷에 순서 번호를 부여, 손실된 패킷 재전송 요청, 수신 확인(ACK) 메커니즘 사용
- 신뢰성 없는 전송의 경우:
- 패킷 손실을 무시, 재전송 시도하지 않음, 최신 데이터 우선 처리
- TCP의 3-way 핸드셰이크를 하지 않으므로 네트워크 지연시간이 낮다
- 현재 상태와 한계점 (2024년 3월 기준):
- Safari 브라우저에서 지원하지 않습니다.
- Node.js에서 기본 지원하지 않습니다.
- 대부분의 웹 서버에서 HTTP/3 지원이 실험적 단계 입니다.
WebRTC(Web Real-Time Communication)란
WebRTC는 웹 브라우저 간에 직접적인 실시간 통신을 가능하게 하는 기술입니다.
이 기술은 별도의 플러그인이나 확장 프로그램 없이도 브라우저 자체에서 P2P 통신을 제공합니다.
- 작동 원리:
- 연결 설정 과정:
- 시그널링 서버를 통해 초기 연결 정보 교환
- ICE 프레임워크를 사용하여 최적의 연결 경로 탐색
- STUN/TURN 서버를 통해 NAT 통과 및 연결 중계
- 주요 구성 요소:
- MediaStream: 오디오/비디오 스트림 처리
- RTCPeerConnection: 피어 간 연결 관리
- 통신 프로토콜:
- ICE(Interactive Connectivity Establishment): 피어 간 최적 연결 경로 찾기
- STUN(Session Traversal Utilities for NAT): NAT 뒤의 공인 IP 주소 확인
- TURN(Traversal Using Relays around NAT): 직접 연결이 불가능할 때 중계 서버 활용
- 보안 특징:
- 모든 통신이 기본적으로 암호화 됩니다
- DTLS(Datagram Transport Layer Security)을 통해서 텍스트, 파일 등 일반 데이터를 암호화 합니다.
- SRTP(Secure Real-time Transport Protocol)을 통해서 미디어 패킷을 암호화 합니다.
- 사용자 동의 없이 카메라/마이크 접근 불가합니다
- 피어 간 직접 통신으로 중간자 공격 위험 감소됩니다.
- 장점:
- 낮은 지연 시간 (P2P 직접 통신)
- 서버 비용 절감 (중계 서버 최소화)
- 브라우저 기본 지원으로 추가 설치 불필요
- 높은 보안성
- 제약사항:
- 시그널링 서버 구현 필요
- NAT/방화벽 환경에 따른 연결 성공률 변동
- 다수 사용자 간 통신 시 대역폭 부하 증가
성능 비교
- 지연 시간
- 롱 폴링: 각 데이터 전송마다 새로운 HTTP 연결을 설정해야 하므로 지연 시간이 길어 실시간 업데이트에는 효율적이지 않습니다. 또한 클라이언트가 아직 새 연결을 열고 있을 때 서버가 이벤트를 보내려고 할 수도 있습니다. 이런 경우에 지연 시간이 훨씬 더 길어집니다.
- 웹 소켓: 하나의 지속적인 연결을 통한 양방향 통신을 사용하여 지연 시간이 가장 짧습니다. 즉각적인 데이터 교환이 중요한 실시간 애플리케이션에 적합합니다.
- Server-Sent Events: 서버에서 클라이언트로 데이터를 보낼 때 마찬가지로 지연 시간이 짧지만, 추가적인 HTTP 요청 없이는 클라이언트에서 서버로 메시지를 다시 보낼 수 없습니다.
- 웹 트랜스포트: 웹 소켓만큼 지연 시간이 짧으며, 보다 효율적인 멀티플렉싱과 혼잡 제어를 위해 HTTP/3 프로토콜을 활용한다는 추가적인 이점이 있습니다.
- 처리량
- 롱 폴링: 연결을 자주 여닫는 오버헤드 때문에 일반적으로 처리량이 더 낮고, 서버 자원을 더 많이 소모합니다.
- 웹 소켓: 지속적인 연결 덕분에 높은 처리량을 낼 수 있습니다. 하지만 클라이언트가 서버의 데이터 전송 속도를 따라가지 못하면 역압(backpressure) 때문에 처리량이 떨어질 수 있습니다.
- Server-Sent Events: 웹 소켓보다 오버헤드가 적어서 많은 클라이언트에게 메시지를 브로드캐스팅하는 데에 효율적입니다. 그에 따라 서버에서 클라이언트로의 단방향 통신에서 처리량이 더 높을 수 있습니다.
- 웹 트랜스포트: 하나의 연결 안에서 단방향과 양방향 스트림 모두에 대해 높은 처리량을 지원하며, 여러 스트림이 필요한 시나리오에서 웹 소켓보다 우수한 성능을 발휘할 것으로 예상됩니다.
- 확장성과 서버 부하
- 롱 폴링: 잦은 연결 때문에 서버 부하가 높아 확장성이 가장 떨어집니다. 그래서 주로 다른 방식이 안될 때 대안으로 사용합니다.
- 웹 소켓: 많은 수의 웹 소켓 연결을 유지하면 서버 부하가 크게 증가하여 사용자가 많은 애플리케이션의 확장성에 영향을 줄 수 있습니다.
- Server-Sent Events: 주로 서버에서 클라이언트로의 업데이트가 필요한 상황에서 더 확장성이 좋습니다. 웹 소켓과 달리 프로토콜 업데이트 같은 작업 없이 일반 HTTP 요청을 사용하기 때문에 연결 오버헤드가 적기 때문입니다.
- 웹 트랜스포트: 확장성이 뛰어나도록 설계되었습니다. HTTP/3의 효율적인 연결 및 스트림 처리 덕분에 웹 소켓이나 SSE보다 서버 부하를 줄일 수 있을 것으로 보입니다.
참조: rxdb