Skip to content

Instantly share code, notes, and snippets.

@jlhg
Last active April 9, 2025 20:57
Show Gist options
  • Save jlhg/b03937bdde3dc9b48494aaca37d25b67 to your computer and use it in GitHub Desktop.
Save jlhg/b03937bdde3dc9b48494aaca37d25b67 to your computer and use it in GitHub Desktop.
Thinking

Let me analyze the user's request. They have provided a URL to the article "Server-Sent Events (SSE) Are Underrated" from Igor's Techno Club. My task is to extract and summarize the content from this article.

The provided information contains the full article text. I need to create a comprehensive summary that captures the key points while maintaining the technical details. Let me structure my response according to the instructions:

  1. I should provide a summary in traditional Chinese (Taiwan usage).
  2. For technical terms or specialized terminology, I should include the original English terms in parentheses.
  3. I should maintain a neutral, objective tone suitable for technical professionals.
  4. I should format the response as article sections in proper markdown.
  5. I should provide citations using the specified format.

The article covers Server-Sent Events (SSE), their advantages, implementations, limitations, and comparisons with WebSockets. I'll organize my summary to cover all these aspects while maintaining the article's structure.

---

伺服器傳送事件 (Server-Sent Events, SSE) 被低估的價值

摘要

伺服器傳送事件 (SSE) 是一種常被忽視但功能強大的技術,提供了比 WebSocket 更簡單的單向實時通訊解決方案。本文探討了 SSE 的基本原理、優勢、實際應用場景以及與 WebSocket 的比較。1

什麼是伺服器傳送事件?

SSE 建立了一個從伺服器到客戶端的單向通訊通道,基於 HTTP 協議運作。與 WebSocket 的雙向連接不同,SSE 保持一個開放的 HTTP 連接用於伺服器向客戶端發送更新。可以將其比喻為廣播電台:伺服器(電台)發送訊息,客戶端(接收器)接收訊息。1

為何 SSE 被低估?

SSE 較少受到關注主要有兩個因素:

  1. WebSocket 的普及:WebSocket 提供的全雙工通訊功能常常使 SSE 的簡單方式被忽視
  2. 被認為有限制:單向通訊性質可能被視為限制,但對許多使用場景而言已經足夠1

SSE 的主要優勢

實現簡單性

SSE 利用標準 HTTP 協議,無需 WebSocket 複雜的連接管理。1

基礎設施兼容性

SSE 與現有 HTTP 基礎設施完美配合:

  • 負載平衡器 (Load balancers)
  • 代理伺服器 (Proxies)
  • 防火牆 (Firewalls)
  • 標準 HTTP 伺服器1

資源效率

相比 WebSocket 具有更低的資源消耗:

  • 單向通訊性質
  • 標準 HTTP 連接使用
  • 無需維護持久性套接字1

自動重連

瀏覽器內建支援:

  • 連接中斷處理
  • 自動重連嘗試
  • 彈性的實時體驗1

明確的語義

單向通訊模式強制執行:

  • 明確的關注點分離
  • 直接的數據流向
  • 簡化的應用程式邏輯1

實際應用場景

SSE 在以下場景表現出色:

  1. 實時新聞推送和社交媒體更新
  2. 股票行情和財經數據顯示
  3. 進度條和任務監控
  4. 伺服器日誌串流
  5. 協作編輯(更新部分)
  6. 遊戲排行榜
  7. 位置追蹤系統1

實現範例

伺服器端 (Flask)

from flask import Flask, Response, stream_with_context
import time
import random

app = Flask(__name__)

def generate_random_data():
    while True:
        data = f"data: Random value: {random.randint(1, 100)}\n\n"
        yield data
        time.sleep(1)

@app.route('/stream')
def stream():
    return Response(
        stream_with_context(generate_random_data()),
        mimetype='text/event-stream'
    )

if __name__ == '__main__':
    app.run(debug=True)

客戶端 (JavaScript)

const eventSource = new EventSource("/stream");

eventSource.onmessage = function(event) {
    const dataDiv = document.getElementById("data");
    dataDiv.innerHTML += `<p>${event.data}</p>`;
};

eventSource.onerror = function(error) {
    console.error("SSE error:", error);
};

程式碼說明

伺服器端元件:

  • /stream 路由處理 SSE 連接
  • generate_random_data() 持續產生格式化事件
  • text/event-stream MIME 類型表示 SSE 協議
  • stream_with_context 維護 Flask 應用程式上下文1

客戶端元件:

  • EventSource 物件管理 SSE 連接
  • onmessage 處理程序處理傳入事件
  • onerror 處理連接問題
  • 自動重連由瀏覽器處理1

限制與考慮因素

實作 SSE 時需注意這些限制:

1. 單向通訊

  • 僅從伺服器到客戶端
  • 需要單獨的 HTTP 請求用於客戶端到伺服器的通訊1

2. 瀏覽器支援

  • 現代瀏覽器支援良好
  • 較舊的瀏覽器可能需要 polyfills1

3. 數據格式

  • 主要支援文字型數據
  • 二進制數據需要編碼(如 Base64)1

4. 最佳化於 HTTP/2

當不使用 HTTP/2 時,SSE 受限於最大開放連接數,特別是在多標籤頁環境中,每個瀏覽器的限制設定很低(6個)。此限制是針對每個瀏覽器+域名組合,使用 HTTP/2 時,最大同時 HTTP 流數由伺服器和客戶端協商(預設為 100)。1

最佳實踐

1. 錯誤處理

eventSource.onerror = function(error) {
    if (eventSource.readyState === EventSource.CLOSED) {
        console.log("Connection was closed");
    }
};

2. 連接管理

// 完成時清理
function closeConnection() {
    eventSource.close();
}

3. 重連策略

let retryAttempts = 0;
const maxRetries = 5;

eventSource.onclose = function() {
    if (retryAttempts < maxRetries) {
        setTimeout(() => {
            // 重連邏輯
            retryAttempts++;
        }, 1000 * retryAttempts);
    }
};

真實案例:ChatGPT 的實現

現代大型語言模型 (LLM) 利用 SSE 進行回應串流。主要 LLM 提供商實現串流的共同模式:

  • 返回 content-type: text/event-stream 標頭
  • \r\n\r\n 分隔的數據區塊
  • 每個區塊包含 data: JSON1

重要說明

雖然 SSE 通常與瀏覽器的 EventSource API 配合使用,但 LLM 實現無法直接使用,因為:

  • EventSource 僅支援 GET 請求
  • LLM API 需要 POST 請求1

OpenAI 實現詳情

OpenAI 的串流實現包括:

  • 基本請求結構使用 stream: true 參數
  • 回應格式為一系列包含增量內容的 JSON 數據塊
  • 流結束標記 data: [DONE]
  • 最終訊息包含令牌使用統計1

結論

SSE 為實時、伺服器到客戶端的通訊提供了優雅的解決方案。其簡單性、效率及與現有基礎設施的整合使其成為許多應用的絕佳選擇。雖然 WebSocket 對雙向通訊仍然有價值,但 SSE 為單向數據流場景提供了更加專注且通常更適合的解決方案。1

Footnotes

  1. Server-Sent Events (SSE) Are Underrated 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment