WebSocket — HTTP의 한계와 실시간 통신
이 토픽을 마치면
HTTP의 한계가 뭔지 알게 되고, WebSocket이 이걸 어떻게 해결하는지 설명할 수 있게 됩니다.
카카오톡은 어떻게 메시지를 바로 보여줄까
카카오톡으로 "밥 먹었어?"를 보내면 상대방 화면에 바로 뜹니다. 1초도 안 걸립니다.
근데 웹의 기본 통신 방식인 HTTP로는 이게 안 됩니다. HTTP는 클라이언트가 요청해야만 서버가 응답하는 구조입니다. 편지와 같습니다 — 상대방이 보내야 받을 수 있고, 내가 먼저 "뭐 새로운 거 있어?"라고 물어봐야 답이 옵니다.
실시간 채팅을 HTTP로 구현하려면? 클라이언트가 0.5초마다 "새 메시지 있어?"라고 서버에 물어봐야 합니다. 이걸 폴링(Polling)이라고 하는데, 메시지가 없어도 계속 물어보니까 서버 부하가 심합니다.
해결책 세 가지
| 방식 | 비유 | 방향 |
|---|---|---|
| HTTP Polling | 0.5초마다 우체통 확인 | 클라이언트 → 서버 (단방향) |
| SSE | 라디오 방송 | 서버 → 클라이언트 (단방향) |
| WebSocket | 전화 | 양방향 |
SSE(Server-Sent Events)는 서버가 클라이언트에게 일방적으로 데이터를 보내는 방식입니다. 주식 시세나 알림처럼 서버→클라이언트 방향만 필요할 때 적합합니다. 근데 클라이언트가 서버에 보내려면 별도 HTTP 요청을 해야 합니다.
WebSocket은 전화입니다. 한 번 연결하면 양쪽 다 아무 때나 말할 수 있습니다. 클라이언트도 보내고, 서버도 보냅니다. 연결을 끊을 때까지 계속 열려 있습니다.
WebSocket이 동작하는 방식
처음에는 HTTP로 시작합니다. "우리 WebSocket으로 전환하자"라고 악수(handshake)를 합니다:
클라이언트 → 서버: "WebSocket으로 업그레이드 해주세요" (HTTP 요청)
서버 → 클라이언트: "OK, 전환합니다" (HTTP 101 응답)
이 시점부터 HTTP가 아닌 ws:// 프로토콜로 통신한번 연결되면 HTTP처럼 매번 헤더를 주고받지 않습니다. 데이터만 오갑니다. 그래서 오버헤드가 적고 빠릅니다.
실제로 쓸 때
WebSocket 원시 API도 있지만, 실무에서는 socket.io 같은 라이브러리를 씁니다. 연결이 끊겼을 때 자동 재연결, 방(room) 관리 등을 다 해주기 때문입니다.
// 서버 (Node.js + socket.io)
io.on('connection', (socket) => {
socket.on('chat', (msg) => {
io.emit('chat', msg); // 모든 클라이언트에게 전달
});
});// 클라이언트
const socket = io('http://localhost:3000');
socket.emit('chat', '밥 먹었어?'); // 서버에 보내기
socket.on('chat', (msg) => { // 서버에서 받기
console.log(msg);
});서버에서 emit, 클라이언트에서 emit — 양쪽 다 보낼 수 있습니다. 이게 양방향의 핵심입니다.
언제 뭘 쓰나
| 상황 | 추천 |
|---|---|
| 일반 API 호출 (게시판 CRUD) | HTTP |
| 서버→클라이언트 단방향 알림 | SSE |
| 실시간 채팅, 멀티플레이어 게임 | WebSocket |
| 주식 시세 실시간 업데이트 | SSE 또는 WebSocket |
대부분의 웹 기능은 HTTP로 충분합니다. "서버가 먼저 클라이언트에게 뭔가를 보내야 하는가?"를 기준으로 판단하면 됩니다.
WebSocket 쓸 때 주의할 점
WebSocket은 연결을 계속 열어두기 때문에 HTTP와 다른 문제가 생깁니다:
연결이 끊기면? — 사용자가 지하철 터널에 들어가면 연결이 끊깁니다. 이때 자동으로 재연결하고, 끊긴 동안 빠진 메시지를 복구해야 합니다. socket.io가 재연결은 해주지만, 메시지 복구는 직접 구현해야 합니다.
동시 접속자가 많으면? — HTTP는 요청-응답 후 연결을 끊지만, WebSocket은 사용자 한 명당 연결 하나를 계속 물고 있습니다. 동시 접속 1만 명이면 서버가 1만 개의 연결을 관리합니다. 서버 리소스 관리가 HTTP보다 까다롭습니다.
보안 — WebSocket도 HTTPS처럼 암호화된 wss:// 프로토콜을 써야 합니다. ws://(암호화 없음)는 중간에서 데이터를 엿볼 수 있습니다.
핵심
HTTP는 편지(요청해야 응답), WebSocket은 전화(양쪽 아무 때나 통신)입니다. WebSocket은 HTTP로 악수한 뒤
ws://프로토콜로 전환되며, 연결이 끊길 때까지 열려 있습니다. 대부분은 HTTP로 충분합니다. **"서버가 먼저 보내야 하는가?"**가 판단 기준입니다.