[Network] 웹 통신 (SSE, Poling, LongPoling)

유얌얌·2024년 11월 7일

CS

목록 보기
10/15

웹 통신

웹 애플리케이션 개발에서 클라이언트와 서버간의 통신은 필수적 요소
이를 위해 주로 사용되는 두 가지 프로토콜은 HTTP (HyperText Transfer Protocol)WebSocket가 있다.

HTTP

요청/응답 모델을 기반으로 하는 비연결성 프로토콜
클라이언트가 서버에 요청을 보내고, 서버는 이에 대한 응답을 보냄

  • 웹 페이지를 로드하거나 폼 데이터를 전송하는 등의 기본적인 웹 애플리케이션에 적합

Web Socket

클라이언트와 서버 간에 지속적인 연결을 유지하는 양방향 통신 프로토콜
실시간으로 데이터를 주고받을 수 있음

  • 한 번의 핸드셰이크를 통해 연결을 수립한 후, 연결이 유지되는 동안 양방향 통신을 가능하게함

이 중에서도 HTTP 프로토콜을 사용한 실시간 구현 방식은 3가지가 있음

  1. Server-Sent-Events(SSE)
  2. Polling
  3. Long Polling

1. Server-Sent-Events(SSE)

HTTP 프로토콜을 통해 서버에서 클라이언트로, 단방향으로 Event를 전송하는 통신 기법
브라우저의 요청없이도 언제든 서버가 새로운 데이터를 보내는 것이 가능

특징

  • 클라이언트에서 매번 요청없이 한 번의 연결을 통해 서버와 통신을 원하는 경우 사용
  • WebSocket 방식보다 간단하고 가벼움
  • 서버로부터 지속적인 업데이트를 받을 수 있음
  • 호출을 통해 닫힐 때까지 연결

사용

  • 채팅 애플리케이션
  • 실시간 알림 시스템

구현

  1. 이벤트를 생성하는 스크립트의 URL을 사용하여 새 EventSource 객체 생성
    EventSource 객체를 통해 서버와 연결
const eventSource = new EventSource(url)
  1. 서버의 메시지들은 event에 명시된 이름 eventname 부분의 이벤트로 수신됨
eventSource.addEventListener('eventname', (event) => {
	//event가 오면 할 동작
})
  1. 에러 핸들링
evtSource.onerror = function (e) {
  alert("EventSource failed.");
};
  1. 이벤트 스트림 닫기
evtSource.close();

2. HTTP Poling

클라이언트가 일정 간격으로 서버에 요청을 보내 데이터를 받아오는 방식

특징

  • 구현이 간단함
  • HTTP 프로토콜을 사용하기 때문에 호환성이 좋음
  • 실시간 데이터를 주고받을 수 있음 (실시간 통신)

  • 일정 간격으로 클라이언트가 서버에 요청을 보내기 때문에 실시간성이 떨어질 수 있음
  • 불필요한 요청(트래픽)이 다수 발생할 수 있음 (업데이트된 데이터가 없는데 시간에 맞춰 요청을 보냄)
  • 다수의 클라이언트에게 동시에 이벤트가 발생될 경우 서버의 부담 up

사용

  • 구현이 간단하고 호환성이 중요한 경우

구현

주로 Timer를 이용한 Polling 방식으로 구현

// React Code
useEffect(() => {
  const fetchData = async () => {
    try {
      const response = await fetch('/api/data');
      if (response.ok) {
        // ...
      }
    } catch (error) {
      // ...
    }
  };

  // fetchData 함수를 호출하여 데이터 업데이트 (5초 간격으로 실행)
  const pollingInterval = setInterval(fetchData, 5000);

  return () => clearInterval(pollingInterval);
}, []);

3. HTTP Long Poling

기본 Poling보다 더 나은 방식
클라이언트에서 요청을 보내고 응답이 올 때까지 기다린다음 응답을 처리하고 스스로 다시 요청을 보냄

특징

  • 구현이 쉬움
  • 지연 없이 메시지를 전달
  • 일반 Poling보다 서버의 부담이 감소
  • 이벤트들의 시간 간격이 좁다면 Poling과의 차이가 거의 X
  • 다수의 클라이언트에게 동시에 이벤트가 발생될 경우 서버의 부담 up

사용

  • 구현이 간단하고 호환성이 중요한 경우
  • Poling의 서버 비용이 부담스러운 경우

구현

async function subscribe() {
  // fetch 요청을 보내어 서버와 연결
  let response = await fetch("/subscribe");

  if (response.status == 502) {
    // 서버가 응답을 지연시키면 502 에러 발생
	// 재연결
    await subscribe();
  } else if (response.status != 200) {
    // 응답이 성공이면 메시지 표시하고 다시 호출해서 연결
    showMessage(response.statusText);
    // 1초 대기
    await new Promise(resolve => setTimeout(resolve, 1000));
    await subscribe();
  } else {
    // 메시지 표시
    let message = await response.text();
    showMessage(message);
    // subscribe() 호출해서 다음 메시지를 얻기 위해 다시 연결
    await subscribe();
  }
}

subscribe();
SSE에 대해 설명해보세요

Server-Sent-Events는 HTTP 프로토콜을 사용해 서버에서 클라이언트로 단방향으로 Event를 전송하는 통신 기법입니다.
브라우저의 요청없이도 언제든 서버가 새로운 데이터를 보내는 것이 가능하며 Web Socket보다 구현이 간단하고 가볍다는 특징이 있습니다.

Poling과 Long Poling의 차이는?

Poling은 일정간격을 두고 서버에 계속해서 요청을 보내는 반면,
Long Poling은 서버에서 응답이 오면 새로 연결하여 서버에 요청을 보냅니다.
때문에 Long Poling이 기본적인 Poling보다 서버에 부담이 덜할 수 있다는 특징이 있습니다.

출처

MDN - Server-Sent Events 사용하기
웹소켓과 HTTP 폴링을 이용한 실시간 통신 구현
자바스크립트 - 롱폴링
웹소켓과 HTTP의 차이점 및 실시간 통신 구현
SSE
React와 SSE(Server Sent Events)로 실시간 채팅 구현하기

profile
조금씩이라도 꾸준하게

0개의 댓글