웹소켓은 웹상에서 브라우저 (클라이언트)와 서버 간의 양방향 통신을 가능하게 하는 고급 기술입니다. 이는 HTTP 프로토콜의 한계를 극복하고 (ex. 클라이언트가 HTTP URL 요청을 할 때에만 → 사용자는 서버로부터 새로운 정보를 받아보기 위해서는, 반드시 새로운 HTTP URL을 요청해야함), 실시간 데이터 교환을 필요로 하는 애플리케이션을 위해 설계되었습니다. 웹소켓 프로토콜은 "ws://" 및 보안 연결을 위한 "wss://" 스킴을 사용하며, 한 번의 핸드셰이크를 통해 연결이 이루어진 후에는 연결을 유지하고 양방향으로 데이터를 송수신할 수 있습니다.
기존의 HTTP 프로토콜은 클라이언트가 서버에 요청을 보내고, 서버가 응답을 반환하는 단방향 통신 방식입니다. 서버가 자체적으로 클라이언트에 정보를 전송할 수 없는 구조로, 실시간으로 데이터를 교환해야 하는 애플리케이션에는 적합하지 않았습니다.
실시간 통신을 구현하기 위해 클라이언트는 주기적으로 서버에 데이터를 요청하는 폴링 기법을 사용했습니다. 이는 네트워크 리소스와 서버 부하를 증가시키는 비효율적인 방법으로, 불필요한 트래픽을 많이 발생시키고, 실시간 반응성을 제대로 제공하지 못했습니다.
HTTP 요청/응답은 헤더와 쿠키 정보를 매번 전송해야 하므로, 작은 데이터를 주고받는 경우에도 상대적으로 큰 오버헤드가 발생했습니다.
이러한 HTTP의 한계를 극복하기 위해 웹소켓 프로토콜이 개발되었습니다. 웹소켓은 다음과 같은 특징을 가지고 있습니다
클라이언트와 서버 간에 양방향 통신이 가능하여, 서버에서도 클라이언트로 직접 데이터를 보낼 수 있습니다. 이를 통해 실시간 웹 애플리케이션의 구현이 용이해졌습니다.
핸드셰이크 과정을 통해 초기 연결이 설정된 후에는 해당 연결을 유지하며, 데이터 교환이 필요할 때마다 즉시 데이터를 주고받을 수 있습니다.
데이터 전송 시 추가적인 HTTP 헤더가 필요 없으므로, 오버헤드가 크게 감소하고, 이는 특히 작은 데이터를 빈번하게 전송해야 하는 애플리케이션에서 유리합니다.
웹소켓은 실시간 채팅 애플리케이션, 온라인 게임, 실시간 협업 도구, 금융 거래 플랫폼 등 다양한 분야에서 활용됩니다. 이러한 애플리케이션은 사용자에게 빠르고 부드러운 인터랙션을 제공해야 하며, 웹소켓은 이러한 요구 사항을 만족시키는 데 핵심적인 역할을 합니다.
웹소켓으로만 채팅 서비스를 구현하는 경우, 기본적으로 실시간 양방향 통신은 잘 작동합니다. 하지만, 사용자 수가 많아질 때 여러 가지 문제가 발생할 수 있습니다. 인메모리 문제는 그 중 하나입니다. 웹소켓 연결을 유지하려면 서버 측에서 각 클라이언트의 상태와 연결 정보를 계속해서 유지해야 합니다. 사용자가 많아질수록, 이 정보를 저장하기 위한 메모리 사용량도 증가하게 됩니다. 대규모 시스템에서는 이로 인해 메모리 오버헤드가 심각한 문제가 될 수 있으며, 성능 저하나 시스템의 안정성 문제로 이어질 수 있습니다.
웹소켓만으로 채팅 서비스를 구현하는 것이 어려운 이유는 다음과 같습니다
웹소켓은 단순한 메시지 전달만을 담당하며, 메시지의 포맷이나 라우팅에 대한 규칙을 제공하지 않습니다. 따라서, 개발자가 모든 메시지 관리 로직을 직접 구현해야 합니다.
사용자 수가 증가함에 따라 서버를 확장(스케일 아웃)해야 할 필요가 있습니다. 웹소켓 연결은 상태를 유지하는 연결이기 때문에, 로드 밸런서를 통한 여러 서버 간의 연결 분배 및 상태 동기화가 필요합니다.
이런 문제들을 해결하기 위해 STOMP와 메시지 브로커가 사용됩니다.
STOMP(Simple Text Oriented Messaging Protocol) 같은 상위 레벨의 메시징 프로토콜을 웹소켓 위에서 사용하여 채팅서비스를 구현할 수 있습니다. STOMP는 웹소켓과 같은 전송 계층 위에서 동작하며, 메시지의 형식과 전송 규칙을 정의합니다. STOMP를 사용함으로써, 클라이언트와 서버 간에 주고 받는 메시지의 형태를 표준화할 수 있습니다.
STOMP (Stomp Over WebSocket)는 Simple Text Oriented Messaging Protocol의 약자로, 웹소켓 위에서 작동하는 메시징 프로토콜입니다. STOMP는 텍스트 기반의 간단한 프레임 구조로 메시지를 교환하며, 구독 (subscribe)과 발행 (publish) 모델을 사용합니다. STOMP를 사용하면 메시지의 라우팅, 변환, 브로드캐스트 등을 보다 쉽게 처리할 수 있으며, 개발자는 메시지의 전송과 수신에 집중할 수 있습니다.
대규모 시스템에서는 메시지를 여러 서버에 분산시켜 처리해야 할 수 있습니다. 메시지 브로커는 메시지를 적절한 처리 단위로 라우팅하여, 부하 분산 및 시스템의 확장성을 관리합니다.
메시지 브로커는 메시지를 임시로 저장할 수 있어, 처리 서버가 잠시 다운되더라도 메시지를 잃지 않고, 서버가 복구되면 메시지를 다시 처리할 수 있습니다.
메시지 브로커를 사용하면, 메시지 생산자와 소비자 간의 직접적인 연결 없이도 메시지를 교환할 수 있습니다. 이를 통해 시스템 간의 결합도를 낮추고, 각 시스템의 독립적인 개발과 유지보수를 용이하게 합니다.
웹소켓(WebSocket)은 기존의 HTTP 프로토콜이 가지는 단방향 통신과 비효율적인 폴링 방식의 한계를 극복하고, 클라이언트와 서버 간의 실시간 양방향 통신을 제공하는 핵심 기술입니다. 이를 통해 실시간 채팅, 온라인 게임, 협업 도구, 금융 거래 플랫폼과 같은 고속의 데이터 전송이 필요한 애플리케이션에서 원활한 사용자 경험을 제공할 수 있습니다.
그러나 웹소켓만으로 대규모 시스템을 구현할 경우, 연결 관리와 메모리 사용량 증가 등 여러 가지 문제가 발생할 수 있습니다. 특히 서버 확장성과 상태 동기화에 대한 이슈가 있으며, 이러한 문제를 해결하기 위해 STOMP와 메시지 브로커를 도입하는 것이 중요합니다. STOMP는 메시지 형식과 라우팅 규칙을 제공하며, 메시지 브로커는 부하 분산과 시스템의 탄력성, 결합도 감소를 가능하게 하여 확장성을 높입니다.
따라서, 웹소켓 기반의 실시간 애플리케이션을 설계할 때는 기본적인 웹소켓 통신의 장점을 살리면서도, STOMP와 메시지 브로커를 결합하여 보다 확장 가능하고 안정적인 구조로 설계하는 것이 필수적입니다.