웹 브라우저에서 서버와 클라이언트가 통신할 수 있는 다양한 방법이 존재한다. 그 방법 중 Polling, Long Polling, SSE, Web Socket에 대해 살펴보자!
사실 기존 블로그에서 정리를 했었는데, 다시 한 번 자세히 코드와 함께 정리해보려 한다.
Polling
![]()
Polling이란?
Client가 평범한 http request를 서버로 계속 날려서 이벤트 내용을 전달받는 방식이다.
가장 쉬운 방법이지만, Client가 계속적으로 request를 날리기 때문에 Client가 많아지면 Server의 부담이 급증하게 된다. http request connection을 맺고 끊는 것 자체가 부담이 많은 방식이다. 또한 Client에서 실시간 정도의 빠른 응답을 기대하기도 어렵다.
장점
- 일정하게 갱신되는 서버 데이터의 경우 유용하게 사용할 수 있다.
단점
- Client가 많아지면 Server의 부담이 급증한다.
- Client 측에서 실시간 정도의 빠른 응답을 기대하기 어렵다.
- HTTP Overhead가 발생할 수 있다.
HTTP Overhead?
전송하는 데이터 양에 비해 헤더 정보의 양 증가로 인해 데이터량이나 처리 시간이 증가하는 현상을 말한다.
Long Polling
![]()
Long Polling이란?
Server 측에서 접속을 열어두는 시간을 길게하는 방식이다.
- Client에서 Server로 http request를 날린다.
- Server에 응답에 대한 사용 가능한 데이터가 없으면 계속 기다리다가 Server에서 해당 Client로 전달할 이벤트가 있다면 그 순간 response 메세지를 전달하면서 연결이 종료된다.
- Client에서는 곧바로 다시 http request를 날려서 서버의 다음 이벤트를 기다린다.
응답을 실시간으로 받아야 하는 경우와 적은 수의 사용자가 동시에 사용하는 경우에 선택할 수 있다.
장점
- 일반 Polling 방식보다 Server의 부담이 감소한다.
단점
- 이벤트들의 시간 간격이 좁다면 일반 Polling 방식과 별 차이가 없다.
- 다수의 Client가 동시에 이벤트가 발생될 경우 Server의 부담이 급증한다.
SSE (Server-Sent Events)
![]()
SSE란?
일반적인 TCP Connection과 비슷하며, Client와 Server간 연결된 연결 통로로 데이터를 보내는 방식이다. Server에서 Client로 이벤트를 전달할 때, 해당 요청을 끊지 않고 필요한 메세지만 보내기를 반복하는 형식이다.
Server와 Client 간 SSE 통신을 하기 위해서 처음에 Client에서 Server로 연결 요청을 보내야 한다. EventSource는 SSE 연결 요청을 보내기 위해 Javascript가 제공하는 객체이며, SSE Client API는 EventSource 객체에 포함된다. EventSource는 text/event-stream 포맷으로 이벤트를 전송하는 HTTP 서버에 지속적으로 연결되고, 연결은 EventSource.close() 호출로 종료되기 전까지 지속된다.
EventSource.onopen: 서버와 연결이 open 됐을 때 호출하는 이벤트 핸들러EventSource.onmessage: 서버로부터 message를 수신했을 때 호출하는 이벤트 핸들러EventSource.onerror: 에러가 발생하거나 EventSource 객체에서 error event가 감지되었을 때 호출하는 이벤트 핸들러
장점
- Long Polling에 비해 응답마다 다시 요청을 하지 않아도 되므로 효율적이다.
단점
- 연결 시간이 길어질수록 연결 유효성 관리의 부담이 발생한다.
- HTTP 통신을 하기 때문에 Request, Response 헤더가 불필요하게 크다.
Web Socket
![]()
Web Socket이란?
기존 단방향 HTTP 프로토콜과 호환되어 양방향 통신을 제공하기 위해 개발된 프로토콜로, 한 번 연결이 수립되면 Client와 Server 모두 자유롭게 데이터를 보낼 수 있다.
HTTP를 이용해서 연결을 수립하며, 연결이 된 이후에도 연결을 할 때 사용했던 포트인 80과 443 포트를 사용한다. 추가로 방화벽을 열지 않아도 된다.
HTTP 규격인 CORS 적용이나 인증 등의 과정을 기존과 동일하게 가져갈 수 있으며, OSI 7 Layer의 4계층(network layer)의 TCP에 의존한다.
- Client가 Server에게 HTTP로 websocket 연결 요청
- Server가 Client에게 HTTP로 websocket 연결 승인
- 양방향 연결로 Server와 Client가 통신
- Client와 Server 중 하나에 의해 양방향 연결 종료
Handshake가 끝나면 HTTP 프로토콜을 websocket 프로토콜로 변환하여 통신한다.
장점
- 기존의 80, 443 포트로 접속을 하므로 추가로 방화벽을 열지 않고도 양방향 통신이 가능하다.
- HTTP 규격인 CORS 적용이나 인증 등의 과정을 기존과 동일하게 가져갈 수 있다.
단점
- websocket 프로토콜을 처리하기 위해 전이중 연결과 새로운 websocket 서버가 필요하다.
React에 적용하기
Polling 적용하기
Polling 작업을 위해
setInterval을 사용하여 데이터를 요청할 수 있다.
const [rankList, setRankList] = useState("");
// API 데이터 호출 함수
const dataAPI = async () => {
const rankAPI = await instance.get(`/url/${id}`);
setRankList(rankAPI.data);
};
useEffect(() => {
let polling = setInterval(() => {
dataAPI();
}, 60000);
// 페이지에 벗어날 경우 polling X
return () => {
clearInterval(polling);
};
}, []);
SSE 적용하기
const [ticket, setTicket] = useState({});
useEffect(() => {
const eventSource = new EventSource("http://localhost:3000/sse");
eventSource.onmessage = (event) => {
setTicket(JSON.parse(event.data));
};
return () => {
eventSource.close();
};
}, []);
return (
<div>
<p>{ticket.key}</p>
<p>{ticket.fields.summary}</p>
</div>
);
< 참조 : https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-Polling-Long-Polling-Server-Sent-Event-WebSocket-%EC%9A%94%EC%95%BD-%EC%A0%95%EB%A6%AC
https://warmth424.tistory.com/18
https://doozi0316.tistory.com/entry/WebSocket%EC%9D%B4%EB%9E%80-%EA%B0%9C%EB%85%90%EA%B3%BC-%EB%8F%99%EC%9E%91-%EA%B3%BC%EC%A0%95-socketio-Polling-Streaming
https://www.crocus.co.kr/m/1826 >