NestJS로 웹 프로젝트를 진행하면서 실시간 채팅 기능을 구현하기 위해 WebSocket(웹 소켓)을 사용하였다. 웹 소켓은 실시간 통신이 필요할 때 사용되는 기술인 것은 알고 있었지만, 프로젝트를 진행하면서 웹 소켓에 대해서 좀 더 이해하고 싶어서 공부를 하게 되었다.
Web Socket 개념과 배경
Web Socket 이전
웹 소켓은 실시간 통신이 필요할 때 사용되는 프로토콜이다. 웹 소켓이 등장하기 전에는 HTTP 프로토콜을 사용하여 인터넷 통신을 하였다. HTTP 통신이란 클라이언트가 요청을 하면 서버가 응답을 하는 반이중 통신 방식이다.
즉, HTTP는 클라이언트의 요청이 있어야만 서버가 클라이언트에게 데이터를 전달할 수 있는 구조이다. 만약 HTTP로 실시간 기능을 구현해야 한다면 어떻게 해야할까?
클라이언트가 서버에 계속 요청을 하는 방법을 생각해 볼 수 있다. 하지만 이는 트래픽을 증가시키기에 서버 비용이 증가할 수 밖에 없는 구조이다. 또한 이는 실시간도 아니다.
다른 방법으로는 계속 요청하는 것이 아닌 일정 주기를 두고 요청을 하는 것이다. 이러한 방법을 Pollling(폴링)이라고 한다. 하지만 이 방법도 실시간이 아니며, 불필요한 요청이 아직도 많다는 것이다.
이 외에도 요청을 받고 응답을 보류해둔 뒤 데이터가 생기면 응답을 해주는 Long Polling(롱 폴링) 방식과 클라이언트가 한 번 요청하면 서버는 HTTP 통신을 종료하지 않고, 데이터가 생길 때마다 계속 응답하는 Server-Sent Event(서버 센트 이벤트) 방식도 있다.
서버 센트 이벤트는 줄여서 "SSE"라고도 불림
하지만 이러한 방식은 전부 실시간 통신으로 보기 힘들고, 클라이언트는 응답을 받기만 가능한 구조로 양방향도 아니다.
Web Socket(웹 소켓)이란?
웹 소켓은 전이중 통신을 사용하며 TCP 에 의존하여 실행된다. 전이중 통신이란 클라이언트와 서버가 양방향으로 통신할 수 있음을 나타낸다. 이를 통해 클라이언트와 서버는 서로 데이터를 주고 받을 수 있다. 그렇다면 웹 소켓은 어떻게 전이중 통신을 가능하게 하는 것일까?
웹 소켓의 핵심은 초기 연결 과정이다. 아래 그림과 같이 클라이언트는 서버에게 소켓을 연결하자고 요청한다. 이때 클라이언트는 요청 헤더를 통해서 서버에게 요청한다. 헤더에는 WebSocket 방식으로 upgrade 하자는 요청이 포함된다.
서버는 이 요청에 응답하여 소켓 연결을 실행한다. 이 과정을 Handshake(핸드셰이크)라고 하며 이는 연결을 설정하기 위한 과정이다. 이 과정을 통해 클라이언트와 서버는 지속적 연결이 가능해지며 실시간으로 데이터를 보내고 받을 수 있다.
그리고 이와 같이 실시간 기능이 가능한 이유는 TCP를 기반으로 하였기 때문이다. TCP를 기반으로 한 웹 소켓은 순서가 보장되어 있기 때문에 데이터가 손실되거나 뒤죽박죽 섞이는 일이 없어진다. 그렇기에 안정적인 양방향 통신이 가능한 것이다.
마무리
공부한 것을 저만의 방식으로 작성한 글입니다. 따라서 틀린 정보가 공유될 수도 있으니 참고만 하되 꼭 공식문서를 통해서 공부하시길 바랍니다. 또한 틀린 부분 지적해주시면 감사하겠습니다!
'Web Development' 카테고리의 다른 글
왜 Transaction이 필요하고 중요할까? (3) | 2025.08.17 |
---|---|
Google OAuth 다중 계정 로그인 문제 해결 (5) | 2025.08.07 |
JWT vs 세션, 어떤 로그인 방식을 선택할까? (0) | 2025.07.22 |
순환 참조 문제 해결(NestJS) (0) | 2024.04.10 |
비동기 함수(async function), Promise 란? (0) | 2024.03.12 |