首頁  >  文章  >  後端開發  >  SSE最簡單的demo(伺服器傳送事件)

SSE最簡單的demo(伺服器傳送事件)

DDD
DDD原創
2024-11-24 06:27:12488瀏覽

介紹

伺服器傳送事件 (SSE) 是一種 Web 技術,可讓伺服器透過 HTTP 將即時更新推送到客戶端。與 WebSocket 不同,SSE 實作起來更簡單,因為它使用從伺服器到瀏覽器的單向通訊通道,並透過常規 HTTP 連線工作。它對於需要定期更新的應用程式特別有用,例如即時比分、通知或即時監控儀表板。

我創建了這個演示,因為我目前正在開發一個應用程序,人工智慧可以在其中討論各種主題。我想實現一些類似流的功能,並發現了名為“SSE”的技術。

演示概述

此示範展示如何使用伺服器傳送事件 (SSE) 將即時更新從 API 傳送到瀏覽器。在此範例中,瀏覽器顯示伺服器發送的一系列範例訊息。該演示的簡單性使其成為了解 SSE 如何運作並將其整合到您的專案中的絕佳起點。

示範影片

下面的影片示範了伺服器發送事件 (SSE) 示範如何即時運作。觀看此影片將使您更了解客戶端和伺服器如何互動以提供即時更新。

The simplest demo on SSE(Server-Send Events)

執行

伺服器發送事件(SSE)演示的核心實作分為兩部分:前端和後端。完整的原始程式碼可在 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 的 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最簡單的demo(伺服器傳送事件)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn