>  기사  >  백엔드 개발  >  SSE(Server-Send Events)에 대한 가장 간단한 데모

SSE(Server-Send Events)에 대한 가장 간단한 데모

DDD
DDD원래의
2024-11-24 06:27:12488검색

소개

서버 전송 이벤트(SSE)는 서버가 HTTP를 통해 클라이언트에 실시간 업데이트를 푸시할 수 있게 해주는 웹 기술입니다. WebSocket과 달리 SSE는 서버에서 브라우저로의 단방향 통신 채널을 사용하고 일반 HTTP 연결을 통해 작동하므로 구현이 더 간단합니다. 실시간 점수, 알림, 실시간 모니터링 대시보드 등 주기적인 업데이트가 필요한 애플리케이션에 특히 유용합니다.

저는 현재 AI가 다양한 주제에 대해 토론하는 애플리케이션을 개발하고 있기 때문에 이 데모를 만들었습니다. 스트림과 같은 기능을 구현하고 싶었는데 "SSE"라는 기술을 발견했습니다.

데모 개요

이 데모에서는 SSE(서버 전송 이벤트)를 사용하여 API에서 브라우저로 실시간 업데이트를 보내는 방법을 보여줍니다. 이 예에서 브라우저는 서버에서 보낸 일련의 샘플 메시지를 표시합니다. 이 데모는 단순하기 때문에 SSE의 작동 방식을 이해하고 이를 프로젝트에 통합하기 위한 훌륭한 출발점이 됩니다.

데모 비디오

아래는 SSE(Server-Sent Events) 데모가 실시간으로 작동하는 방식을 보여주는 동영상입니다. 이 비디오를 시청하면 클라이언트와 서버가 상호 작용하여 실시간 업데이트를 제공하는 방법을 더 잘 이해할 수 있습니다.

The simplest demo on SSE(Server-Send Events)

구현

서버 전송 이벤트(SSE) 데모의 핵심 구현은 프런트엔드와 백엔드의 두 부분으로 나뉩니다. 전체 소스 코드는 GitHub: sse-demo 저장소에서 확인할 수 있습니다.

프런트엔드(ui/src/app/page.tsx)

프런트엔드는 React로 구축되었으며 SSE 연결을 시작 및 중지하는 버튼을 제공하여 서버의 실시간 메시지를 표시합니다. 주요 내용은 다음과 같습니다.

  1. SSE에 연결: handlerStartConnection 함수는 /events 엔드포인트에 연결된 EventSource 개체를 생성합니다. 메시지, 열린 이벤트 및 오류 이벤트를 수신합니다.

    • onmessage: 수신 메시지를 처리하고 메시지 상태를 업데이트합니다.
    • onopen: 연결이 설정되면 기록합니다.
    • onerror: 오류를 처리하고, 세부 정보를 기록하고, 필요한 경우 연결을 종료합니다.
  2. 연결 중지: handlerStopConnection 함수는 SSE 연결을 닫고 정리합니다.

  3. UI: 이 페이지에는 시작/중지 버튼과 메시지 표시 목록이 있는 간단한 인터페이스가 포함되어 있습니다.

"use client";

import type React from "react";
import { useState } from "react";

const App: React.FC = () => {
  const [messages, setMessages] = useState<string[]>([]);
  const [eventSource, setEventSource] = useState<EventSource | null>(null);

  const handleStartConnection = () => {
    const newEventSource = new EventSource("http://localhost:8080/events");

    const handleOnMessage = (event: MessageEvent) => {
      console.log("onmessage", event.data);
      setMessages((prev) => [...prev, event.data]);
    };

    const handleOnOpen = () => {
      console.log("Connection established");
    };

    const handleOnError = (error: Event) => {
      console.error("onerror", error);
      console.log("readyState:", newEventSource.readyState);
      console.log("Connection error occurred.");
      newEventSource.close();
      setEventSource(null);
    };

    const handleOnClose = () => {
      console.log("Connection is being closed by the server.");
      newEventSource.close();
      setEventSource(null);
    };

    newEventSource.onmessage = handleOnMessage;
    newEventSource.onopen = handleOnOpen;
    newEventSource.onerror = handleOnError;
    newEventSource.addEventListener("close", handleOnClose);

    setEventSource(newEventSource);
  };

  const handleStopConnection = () => {
    if (eventSource) {
      eventSource.close();
      setEventSource(null);
      console.log("Connection closed");
    }
  };

  return (
    <div>
      <h1>Server-Sent Events Demo</h1>
      <button
        type="button"
        onClick={handleStartConnection}
        disabled={!!eventSource}
        className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded disabled:opacity-50"
      >
        Start Connection
      </button>
      <button
        type="button"
        onClick={handleStopConnection}
        disabled={!eventSource}
        className="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded disabled:opacity-50 ml-2"
      >
        Stop Connection
      </button>
      <ul>
        {messages.map((message, index) => (
          <li key={`${index}-${message}`}>{message}</li>
        ))}
      </ul>
    </div>
  );
};

export default App;

백엔드(api/main.go)

백엔드는 Go용 Gin 프레임워크를 사용하여 구축되었으며 다음과 같은 주요 기능을 포함합니다.

  1. CORS 구성: 백엔드는 Gin CORS 미들웨어를 사용하여 디버깅 중에 연결을 허용합니다.

  2. SSE 엔드포인트: /events 엔드포인트는 각 메시지 사이에 지연을 두고 미리 ​​정의된 일련의 메시지를 클라이언트에 스트리밍합니다. 주요 구성 요소:

    • 헤더는 텍스트/이벤트 스트림 콘텐츠 유형을 지정하도록 설정됩니다.
    • 메시지는 각 메시지 사이에 2초의 지연을 두고 반복적으로 전송됩니다.
    • 마지막 닫기 이벤트는 연결 종료를 알립니다.
"use client";

import type React from "react";
import { useState } from "react";

const App: React.FC = () => {
  const [messages, setMessages] = useState<string[]>([]);
  const [eventSource, setEventSource] = useState<EventSource | null>(null);

  const handleStartConnection = () => {
    const newEventSource = new EventSource("http://localhost:8080/events");

    const handleOnMessage = (event: MessageEvent) => {
      console.log("onmessage", event.data);
      setMessages((prev) => [...prev, event.data]);
    };

    const handleOnOpen = () => {
      console.log("Connection established");
    };

    const handleOnError = (error: Event) => {
      console.error("onerror", error);
      console.log("readyState:", newEventSource.readyState);
      console.log("Connection error occurred.");
      newEventSource.close();
      setEventSource(null);
    };

    const handleOnClose = () => {
      console.log("Connection is being closed by the server.");
      newEventSource.close();
      setEventSource(null);
    };

    newEventSource.onmessage = handleOnMessage;
    newEventSource.onopen = handleOnOpen;
    newEventSource.onerror = handleOnError;
    newEventSource.addEventListener("close", handleOnClose);

    setEventSource(newEventSource);
  };

  const handleStopConnection = () => {
    if (eventSource) {
      eventSource.close();
      setEventSource(null);
      console.log("Connection closed");
    }
  };

  return (
    <div>
      <h1>Server-Sent Events Demo</h1>
      <button
        type="button"
        onClick={handleStartConnection}
        disabled={!!eventSource}
        className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded disabled:opacity-50"
      >
        Start Connection
      </button>
      <button
        type="button"
        onClick={handleStopConnection}
        disabled={!eventSource}
        className="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded disabled:opacity-50 ml-2"
      >
        Stop Connection
      </button>
      <ul>
        {messages.map((message, index) => (
          <li key={`${index}-${message}`}>{message}</li>
        ))}
      </ul>
    </div>
  );
};

export default App;

실행 방법

이 데모를 실행하려면 GitHub 저장소의 README.md 파일을 참조하세요. 여기에는 프로젝트의 프런트엔드와 백엔드를 모두 설정하고 실행하기 위한 단계별 지침이 포함되어 있습니다.

결론

이 데모는 서버에서 보낸 이벤트(SSE)에 대해 간단하면서도 효과적인 소개를 제공하며 서버에서 브라우저로 실시간 메시지를 스트리밍하는 방법을 보여줍니다. 기본에 중점을 두어 핵심 개념을 빠르게 이해하고 자신의 프로젝트에서 SSE를 실험해 볼 수 있도록 설계되었습니다.

이 예제를 시험해 보거나 이를 기반으로 구축하는 데 관심이 있다면 GitHub: sse-demo 저장소에서 전체 소스 코드를 확인하세요.

위 내용은 SSE(Server-Send Events)에 대한 가장 간단한 데모의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.