ホームページ  >  記事  >  バックエンド開発  >  SSE(Server-Send Events)の最も簡単なデモ

SSE(Server-Send Events)の最も簡単なデモ

DDD
DDDオリジナル
2024-11-24 06:27:12487ブラウズ

導入

Server-Sent Events (SSE) は、サーバーが HTTP 経由でクライアントにリアルタイムの更新をプッシュできるようにする Web テクノロジーです。 WebSocket とは異なり、SSE はサーバーからブラウザへの一方向通信チャネルを使用し、通常の HTTP 接続で動作するため、実装が簡単です。これは、ライブ スコア、通知、リアルタイム モニタリング ダッシュボードなど、定期的な更新が必要なアプリケーションに特に役立ちます。

このデモを作成したのは、現在 AI がさまざまなトピックについて話し合うアプリケーションを開発しているためです。ストリームのような機能を実装したいと考えていたところ、「SSE」というテクノロジーを発見しました。

デモの概要

このデモでは、サーバー送信イベント (SSE) を使用して API からブラウザーにリアルタイムの更新を送信する方法を紹介します。この例では、サーバーから送信された一連のサンプル メッセージがブラウザーに表示されます。このデモはシンプルなので、SSE の仕組みを理解し、プロジェクトに統合するための優れた出発点となります。

デモビデオ

以下は、Server-Sent Events (SSE) デモがリアルタイムでどのように動作するかを示すビデオです。このビデオを見ると、クライアントとサーバーがどのように対話してリアルタイムの更新を提供するかについてよりよく理解できます。

The simplest demo on SSE(Server-Send Events)

実装

Server-Sent Events (SSE) デモのコア実装は、フロントエンドとバックエンドの 2 つの部分に分かれています。完全なソース コードは、GitHub: sse-demo リポジトリで入手できます。

フロントエンド (ui/src/app/page.tsx)

フロントエンドは React で構築されており、SSE 接続を開始および停止するボタンを提供し、サーバーからのリアルタイム メッセージを表示します。主なハイライトは次のとおりです:

  1. SSE への接続: handleStartConnection 関数は、/events エンドポイントに接続された EventSource オブジェクトを作成します。メッセージ、オープン イベント、エラー イベントをリッスンします:

    • onmessage: 受信メッセージを処理し、メッセージの状態を更新します。
    • onopen: 接続が確立されたときのログを記録します。
    • onerror: エラーを処理し、詳細をログに記録し、必要に応じて接続を閉じます。
  2. 接続の停止: handleStopConnection 関数は 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 用の Jin フレームワークを使用して構築されており、次の主要な機能が含まれています。

  1. CORS 構成: バックエンドは、Gin CORS ミドルウェアを使用して、デバッグ中の接続を許可します。

  2. SSE エンドポイント: /events エンドポイントは、各メッセージの間に遅延を設けて、一連の事前定義されたメッセージをクライアントにストリーミングします。主要コンポーネント:

    • ヘッダーは、テキスト/イベント ストリームのコンテンツ タイプを指定するように設定されます。
    • メッセージはループで送信され、各メッセージ間に 2 秒の遅延が生じます。
    • 最後の close イベントは、接続の終了を示します。
"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 ファイルを参照してください。これには、プロジェクトのフロントエンドとバックエンドの両方を設定して実行するための段階的な手順が含まれています。

結論

このデモは、Server-Sent Events (SSE) のシンプルかつ効果的な紹介を提供し、サーバーからブラウザーにリアルタイム メッセージをストリーミングする方法を示します。基本に焦点を当てることで、核となる概念をすぐに理解し、独自のプロジェクトで SSE の実験を開始できるように設計されています。

この例を試してみたり、この例に基づいて構築したりすることに興味がある場合は、GitHub の完全なソース コード (sse-demo リポジトリ) をチェックしてください。

以上がSSE(Server-Send Events)の最も簡単なデモの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。