Intro

대용량 데이터를 처리하며 저장 작업을 수행할 때 긴 대기시간이 발생하게 되었다.
사용자 입장에서는 Confirm 버튼을 클릭한 뒤, 화면에 추가적인 이벤트나 피드백이 전혀 없으니 멈춘 것으로 오해할 수도 있겠다는 생각이 들었다. 이를 해결하기 위해 단순히 Skeleton UI로 가려둘 수도 있겠지만, 작업이 오래 걸리는 경우에는 현재 어느 정도 처리되었는지 진행 상황을 실시간으로 확인하면 좋겠다는 생각이 들었다.
Material UI LinearProgress 컴포넌트를 사용하면 진행 상황을 시각적으로 보여줄 있을 같은데,
어떻게 서버 상태를 확인하지? 에서 출발한 오늘의 포스팅..
글이 길어질것 같으니 2개로 나누어서 작성해야지. 일단 오늘은 서버와 실시간으로 통신할 있는 방법들에 대해 알아보자.

1. 서버와 실시간으로 통신할 수 있는 방법

서버와 실시간으로 통신할 수 있는 방법에는 여러가지가 있지만,
내가 알아본 바로는 4가지의 방법이 있었다.

  • Polling (Short Polling)
  • Long Polling
  • WebSocket
  • SSE(Server-Sent Events)

아래에서 각각의 방법에 대해 자세하게 풀어보자.

 

2. Polling (Short Polling)

2-1) 특징

  • 가장 단순한 방식으로, 정해진 간격(interval)으로 주기적인 HTTP 요청을 보내어 서버 데이터를 가져오는 방법
  • 예를 들어, 5초에 한 번씩 GET /api/data 요청을 보내어 새로운 데이터가 있나 계속 확인!
  • 특별한 프로토콜이나 서버 설정이 필요 없고, 기존의 HTTP GET/POST 방식만으로도 충분히 구현이 가능

2-2) 동작 방식

  1. 클라이언트가 일정 시간 간격(ex: 5초)으로 서버에 요청을 보냄
  2. 서버는 즉시(혹은 빠르게) 현재 상태/데이터를 응답으로 내려줌
  3. 클라이언트는 받은 데이터를 화면에 업데이트하고, 다시 다음 주기 때 요청을 반복

2-3) 장단점

  • 장점
    • 구현이 매우 간단 (ex: setInterval()에 AJAX 요청)
    • 추가 프로토콜(WebSocket)이나 특별한 서버 설정이 없어도, 기존 HTTP만으로 구현 가능
    • 구형 브라우저 환경에서도 무난히 사용 가능
  • 단점
    • 데이터가 변경되지 않았는데도 주기적으로 요청을 보내므로 불필요한 트래픽이 발생할 수 있음.
    • 요청 간격 사이에 발생한 이벤트는 즉시 감지하기 어렵다. (ex: 5초 주기로 요청하면, 최대 5초 늦게 알게 됨)

3. Long Polling

3-1) 특징

  • Polling(Short Polling)과 마찬가지로 HTTP 요청을 사용하지만, 서버가 응답을 지연시키는 기법
  • 즉, 서버 입장에서 “새로운 데이터가 생길 때까지 기다렸다가 응답”을 보내는 형태
  • 클라이언트는 응답을 받은 즉시 다시 요청을 보내어 연결을 이어가는 방식으로, 마치 실시간처럼 데이터 받을 수 있음

3-2) 동작 방식

  1. 클라이언트가 서버에 요청을 보냄
  2. 서버는 새로운 데이터(혹은 이벤트)가 발생할 때까지 연결을 유보(hold)함
  3. 데이터가 준비되면 서버가 즉시 응답을 전송
  4. 클라이언트는 응답을 받으면, 다시 새 요청을 보내서 같은 과정을 반복

3-3) 장단점

  • 장점
    • Polling보다 “실시간성”이 상대적으로 높다. (서버 이벤트가 생기면 즉시 응답)
    • 여전히 HTTP 기반이며, 별도의 WebSocket 설정이 필요 없음.
  • 단점
    • 서버 자원 점유: 응답을 보류하고 있기 때문에, 많은 사용자가 동시에 접속하면 서버 연결이 많이 소모될 수 있음.
    • 연결이 끊기고, 재연결이 반복되는 구조이므로, 클라이언트와 서버 모두 추가 로직이 필요할 수 있음.

3. WebSocket

4-1) 특징

  • 양방향(Full-duplex) 통신을 제공하는 독립된 프로토콜(ws:// 또는 wss://).
  • 초기에는 HTTP 핸드셰이크로 연결을 설정한 뒤, 성공 시 WebSocket 프로토콜로 업그레이드하여 지속적인 채널을 형성
  • 이후에는 서버와 클라이언트가 자유롭게 이벤트를 주고받을 수 있으므로, 실시간 채팅, 협업, 게임 등에 적합

4-2) 동작 방식

  1. 클라이언트가 HTTP 요청을 보내며 “WebSocket 업그레이드”를 요청
  2. 서버가 이를 수락하면, WebSocket 프로토콜로 전환
  3. 연결이 수립된 후에는 양쪽이 필요할 때마다 메시지를 발행하고, 서로 수신할 수 있음

4-3) 장단점

  • 장점
    • 양방향 통신이 가능해, 클라이언트 -> 서버, 서버 -> 클라이언트 모두 실시간으로 주고받을 수 있음
    • 채팅, 게임, 실시간 협업 등 짧은 지연(latency)을 요구하는 서비스에 탁월
  • 단점
    • 별도의 WebSocket 서버, 라이브러리 또는 설정이 필요하며, 로드밸런서나 프록시를 쓸 때도 추가 설정이 필요할 수 있음
    • 단순히 서버 -> 클라이언트 단방향 이벤트만 필요한 경우에는 오히려 과도한 스펙이 될 수 있음

4. SSE(Server Sent Event)

5-1) 특징

  • HTML5 표준으로, 브라우저가 기본 지원하는 EventSource API를 사용해 서버 -> 클라이언트 단방향 데이터를 스트리밍할 수 있음
  • HTTP 기반으로, “text/event-stream” 형태로 계속 이벤트를 흘려보낸다
  • 서버가 데이터를 Push하는 시점에 클라이언트에서 onmessage 등을 통해 실시간으로 수신 가능

5-2) 동작 방식

  1. 클라이언트(브라우저)에서 new EventSource(url)로 SSE endpoint에 연결
  2. 서버는 HTTP 연결을 유지하면서, 필요한 이벤트가 있을 때마다 일방적으로 푸시(Push)함
  3. 클라이언트는 연결이 끊길 경우 자동 재연결을 시도(브라우저의 EventSource 기본 기능)

5-3) 장단점

  • 장점
    • 자동 재연결: 연결 끊김 시 브라우저가 재접속 시도
    • 설정이 간단하며, 단방향 실시간 알림/로그/이벤트에 가장 적합
    • 기존 HTTP 기반이므로 방화벽/프록시 문제 발생이 비교적 적음
  • 단점
    • 양방향 통신이 안 되어, 클라이언트 -> 서버로 실시간 전송이 필요하면 별도 채널(예: AJAX) 필요
    • 바이너리 전송에는 적합하지 않고, 대부분 텍스트/JSON 형태로 사용

5. 정리

 

  • Short Polling: 쉽고 간단하지만, 주기적 요청으로 불필요한 트래픽이 발생할 수 있음.
  • Long Polling: 실시간에 좀 더 가깝지만, 서버가 응답을 홀드해야 하므로 서버 자원 부담이 큼.
  • WebSocket: 양방향 소통이 뛰어나고 실시간성이 가장 좋지만, 서버/네트워크 설정이 복잡할 수 있음.
  • SSE: 단방향 푸시에 특화되어 있고, 자동 재연결 + 구현 간단이라는 강점이 있음.

 

래퍼런스

클라이언트와 서버간 실시간 통신을 하는 방법

웹소켓을 알아봅시다

SSE (Server Sent Events) - 서버가 그대에게 보낸다

 

마치며

이전에 진행했던 프로젝트에서 웹소켓을 사용해보았었는데, supabase에서 제공하는 간단한 api만 사용했다보니 관련 지식에 대해서 단순히 양방향 소통이 가능한 방법이구나 정도만 알았었다. 이번 경험을 통해 서버와 소통할 수 있는 다양한 방법에 대해 알고, 어떤것이 필요한지 판별하는 과정에서 공부가 많이 되었던것 같다. 다음 편에서는 내가 프로젝트에 적용하게 된 기법에 대해 작성해보겠다!

+ Recent posts