FrontEngineer JungBam

간단하게 SSE 구현하기(프론트) 본문

개발일지

간단하게 SSE 구현하기(프론트)

정밤톨 2023. 7. 29. 17:53

흔히들 사용하는 방법으로 두가지 방법이 있을 수 있다. 

 

1. Socket 통신을 사용하여 지속 연결된 상태에서 변경이 발생할 때에 이벤트를 프론트에 보내주는 방법

2. SSE(server sent event)를 통해서 서버에서 이벤트가 발생했을 때에 프론트가 이벤트를 받는 방법

 socket과 sse의 차이점은 socket통신 자체는 양방향 통신이 가능하다는 것이고 sse는 서버에서 클라이언트로 보내주는 단방향 방식이라는 점이다. 양방향 통신을 유지하기 위해서 서버도 클라이언트의 이벤트를 듣기 위해 동작을 해야하는데, 알림과 같은 기능일 경우에는 서버에서 클라이언트에게만 제공하면되기 때문에 양방향으로 구현하기보다 단방향으로 구현하는 것이 더 탁월한 선택입니다.

프론트에서의 SSE 구현

 간략히 설명하면 EventSource web API를 사용하여 해당 api에서 발생하는 서버의 이벤트와 연결을 하고 서버에서 발생하는 이벤트를 콘솔로 찍어내는 간단한 컴포넌트이다. 리액트 훅을 사용하기 위해서 next.js에서는 클라이언트 컴포넌트로 만들어줘야한다.

 아래에 있는 공식문서 링크에 들어가면 EventSource web API의 각각의 이벤트와 메소드를 확인할 수 있다.

 (아래 코드에서 보듯이 onopen, opmessage, onerror에서 서버에서 발생한 이벤트를 캐치해서 처리하고 close 메소드를 통해서 서버와의 연결을 끝낸다.)

"use client";
import React from "react";

const SSETestPage = () => {
  const source = React.useRef<EventSource>();

  const stopEvent = async () => {
    source.current?.close();
    await fetch("http://localhost:8080/stop");
  };

  React.useEffect(() => {
    source.current = new EventSource("http://localhost:8080/start");

    source.current.onopen = (e) => {
      console.log("sse 시작", { e });
    };

    source.current.onmessage = (event) => {
      console.log("서버에서 온 메시지", { event });

      if (event.data === "end") {
        source.current?.close();
        return;
      }
    };

    source.current.onerror = (err) => {
      console.log("서버 에러", { err });
    };

    return () => {
      stopEvent();
    };
  }, []);

  return (
    <div>
      sse
      <button onClick={() => stopEvent()}>stop</button>
    </div>
  );
};

export default SSETestPage;

 프론트에서 서버에서 발생하는 이벤트를 감시하기 위해서는 EventSource라는 web API를 사용하는데 자세한 내용은 아래 공식문서를 보면 알 수 있다. (공식문서의 내용을 간단하게 정리해보자.)

 앞서 이야기한 것과 동일한 내용인데 websocket과 달리 단방향 통신이라는 점, 그래서 클라이언트에서 서버로 데이터를 보낼 필요가 없을 때 탁월한 선택이 된다는 내용이다.
 

EventSource - Web APIs | MDN

The EventSource interface is web content's interface to server-sent events.

developer.mozilla.org

 

반응형
Comments