AI 大模型爆火的 SSE 技術到底是什麼?萬字長文,一篇讀懂 SSE!

新聞
HongKong
1
03:28 PM · Dec 25 ,2025

本文由45歲老架構師尼恩分享,感謝作者,有修訂和重新排版。

1、引言

你有沒有想過,為什麼 ChatGPT 的回答能逐字逐句地“流”出來?這一切的背後,都離不開一項關鍵技術——SSE(Server-Sent Events)!

1

本文從SSE(Server-Sent Events)技術的原理到示例代碼,為你通俗易懂的講解SSE技術的方方面面。

2、AI大模型實時通信技術專題

技術專題系列文章目錄如下,本文是第 4 篇:

  1. 《全民AI時代,大模型客户端和服務端的實時通信到底用什麼協議?》
  2. 《大模型時代多模型AI網關的架構設計與實現》
  3. 《通俗易懂:AI大模型基於SSE的實時流式響應技術原理和實踐示例》
  4. 《ChatGPT如何實現聊天一樣的實時交互?快速讀懂SSE實時“推”技術 》
  5. 《AI大模型爆火的SSE技術到底是什麼?萬字長文,一篇讀懂SSE! 》(☜ 本文

3、初識SSE

SSE(Server-Sent Events)是一種基於 HTTP 協議的服務器推送技術,允許服務端主動向客户端發送數據流。

SSE  可以被理解為 HTTP 的一個擴展或一種特定用法。它不是一個全新的、獨立的協議,而是構建在標準 HTTP/1.1 協議之上的技術。

SSE 就像是服務器打開了一個“單向數據管道”,服務器通過HTTP 擴展 可以持續不斷地流向瀏覽器,無需客户端反覆發起請求。其實很簡單的:  SSE = HTTP 擴展字段 + Keepalive 長連接。

SSE 提供了一種簡單、可靠的方式來實現服務器向客户端的實時數據推送。它非常適合通知、實時數據更新、日誌流和類似 ChatGPT 的逐字輸出場景。如果你只需要單向通信,SSE 往往是比 WebSocket 更簡單、更輕量的選擇。

SSE 適用於服務器主動向客户端推送數據的場景,如實時通知、動態更新等。

所以,目前 幾乎所有主流瀏覽器都原生支持SSE。

PS:更詳細的SSE技術資料,可以進一步閲讀以下幾篇:

  1. Web端即時通訊技術盤點:短輪詢、Comet、Websocket、SSE
  2. SSE技術詳解:一種全新的HTML5服務器推送事件技術
  3. 詳解Web端通信方式的演進:從Ajax、JSONP 到 SSE、Websocket
  4. 一文讀懂前端技術演進:盤點Web前端20年的技術變遷史
  5. 網頁端IM通信技術快速入門:短輪詢、長輪詢、SSE、WebSocket
  6. 搞懂現代Web端即時通訊技術一文就夠:WebSocket、socket.io、SSE

4、SSE的誕生背景

4.1 短輪詢、長輪詢、Flash 、 WebSocket

在 SSE 技術出現之前,Web 應用要實現服務器向客户端的實時數據推送,主要依賴以下幾種技術,但它們都存在明顯的缺陷。

4.1.1)短輪詢 (Polling):

原理:用短連接請求數據。客户端以固定的時間間隔(例如每秒一次)頻繁地向服務器發送請求,詢問是否有新數據。

缺點:大量請求可能是無效的(無新數據),浪費服務器和帶寬資源,實時性差。

短輪詢的技術流程圖:

2
4.1.2)長輪詢 (Long Polling):

原理:使用長連接請求數據。 客户端發送一個請求,服務器會保持這個連接打開(長連接),直到有新數據可用或超時。一旦客户端收到響應,會立即發起下一個請求。

缺點:雖然減少了無效請求,但每個連接仍然需要客户端發起,服務器需要維護大量掛起的連接,實現複雜。

3

長輪詢 (Long Polling) 的技術突破:減少無效請求,但服務器需維護掛起連接

4.1.3)基於 Flash 的解決方案:

原理:利用 Adobe Flash 插件提供的 Socket 功能實現全雙工通信。

缺點:依賴瀏覽器插件,在移動端(如 iPhone)不受支持,且隨着技術的發展(Flash 被淘汰)已走向消亡。基於 Flash 方法都非原生支持,效率低下或依賴外部插件。

4.1.4)基於 WebSocket的解決方案:

原理:在客户端與服務器之間建立一條全雙工的 TCP 長連接,雙方可隨時互相推送數據。

缺點:

  • 1)需要一次額外的協議升級握手(Upgrade: websocket),對 CDN、防火牆、代理服務器的兼容性不如普通 HTTP;
  • 2)雙向通信能力在“服務器→客户端單向推送”場景下顯得過度設計,增加心跳、重連、幀解析等複雜度;
  • 3)早期瀏覽器支持不一(IE ≤ 9 無原生實現),需要 Polyfill 或 Flash 降級方案。
4

 

WebSocket全雙工通道的革命性:擺脱HTTP束縛,實現真正的實時交互(PS: WebSocket 並不僅是 Web 領域的通訊協議,它屬於複雜度較高的二進制通訊協議)。

4.2 SSE 誕生的核心背景

因此,Web 領域迫切需要一種標準化的、高效的、由瀏覽器原生支持的服務器到客户端的單向通信機制。這就是 SSE 誕生的核心背景。

核心需求:

  • 1)簡單:易於服務器和客户端實現;
  • 2)高效:基於 HTTP/HTTPS,避免不必要的請求開銷;
  • 3)標準:成為 W3C 標準,得到瀏覽器原生支持;
  • 4)自動重連:內置連接失敗後自動重試的機制。

SSE——真正的服務器推送:

5

 

5、SSE的前世今生

SSE 的發展是 Web 標準化進程和實時通信需求共同推動的結果。

下圖概述了其關鍵發展節點:

6

 

讓我們對圖中的關鍵階段進行詳細解讀。

1)誕生背景(2006 年以前):

Web 早期只有“請求-響應”範式,實時需求(股票、IM、行情)只能靠輪詢或長輪詢,延遲高、浪費資源。Comet(長連接 iframe、jsonp、xhr-streaming 等 Hack 方案)出現,但實現複雜、瀏覽器兼容性差、佔用連接數高。

業界急需一種“瀏覽器原生、基於 HTTP、單向服務器推送”的輕量機制。

2)概念提出與標準化 (約 2006-2009年):

SSE 的概念最初作為 HTML5 標準的一部分被提出,由 WHATWG (Web Hypertext Application Technology Working Group) 和 W3C (World Wide Web Consortium) 共同推動。

其設計思想是定義一個簡單的、基於 HTTP 的協議,允許服務器通過一個長連接持續地向客户端發送文本流。

2006 年,Opera 9 在瀏覽器裏率先實現名為 Server-Sent Events 的實驗 API,用 DOM 事件把服務器推送的文本塊餵給頁面。

同期 WHATWG HTML5 草案開始收錄相關章節,定義了 text/event-stream MIME 類型及“event: / data:”行協議。

後來,它從龐大的 HTML5 規範中分離出來,成為了一個獨立的 W3C 標準文檔。

2008 年,SSE 被正式寫入 HTML5 草案,隨後進入 W3C 標準流程。

3)瀏覽器支持與推廣 (約 2010-2015年):

2011年左右,主流瀏覽器(如 Firefox、Chrome、Safari、Opera)開始陸續支持 SSE API。 Firefox 6、Chrome 6、Safari 5、Opera 11.5 陸續完成原生實現;IE 系列缺席(直到 Edge 79 才補票)。

關鍵的障礙:Internet Explorer (包括 IE 11) 始終沒有支持 SSE API。這在一定程度上限制了其早期的廣泛應用,開發者通常需要為此準備降級方案(如回落到長輪詢)。

隨着 Chrome、Firefox 等現代瀏覽器的市場份額不斷上升,以及移動端瀏覽器對 SSE 的良好支持,SSE 逐漸成為開發實時 Web 應用的可信選擇。

2014 年 10 月:HTML5 成為 W3C Recommendation,SSE 作為官方子模塊鎖定最終語法,瀏覽器陣營格局定型。

4)正式推薦與成熟 (2015年至2022 ):

2015-2020 年,WebSocket 與 WebRTC 佔據實時通信話題中心,SSE 主要在企業內部儀表盤、日誌 tail 等低頻場景默默使用。

SSE 由於有 “單向文本流 + 自動重連 + 輕量”  特性,所以沒有被WebSocket 與 WebRTC  踩死, 使其在 IoT 設備、移動端 WebView 中仍保有一席之地。

2015年,W3C 發佈了 Server-Sent Events 的正式推薦標準,標誌着該技術的成熟和穩定。在此期間,前端生態框架(如 React、Vue.js)和後端語言(如 Node.js、Python、Java)都提供了對 SSE 的良好支持,出現了大量易用的庫和示例。

5) 大模型時代的爆發(2022 至今):

雖然 WebSocket 提供了全雙工通信能力,但 SSE 因其簡單的 API、基於 HTTP 帶來的良好兼容性(如無需擔心代理或防火牆問題)、以及自動重連等特性,在只需要服務器向客户端推送數據的場景中(如新聞推送、實時行情、狀態更新、AI 處理進度流式輸出等)成為了更簡單、更合適的選擇。

ChatGPT、Claude 等生成式 AI 需要“打字機”式逐 token 輸出,SSE 天然契合:

  • 1)基於 HTTP/1.1 無需升級協議,CDN 緩存友好;
  • 2)瀏覽器 EventSource API 一行代碼即可接入;
  • 3)文本流可直接承載 JSON Lines 或 markdown 片段。

2022 年底起:OpenAI、Anthropic、Google Bard 均把 text/event-stream 作為官方流式回答協議,社區庫(FastAPI SSE-Star、Spring WebFlux、Node sse.js、Go gin-sse)迎來二次繁榮。

6、SSE的技術特徵

7

 

SSE和WebSocket 都能建立瀏覽器與服務器的長期通信,但區別很明顯:

  • 1)SSE 是單向推送  不是雙向推送, 而且是http協議的一個擴展協議, 使用簡單、自動重連,適合文本類實時推送;
  • 2)WebSocket 是雙向通信,不是 http協議的一個擴展協議,WebSocket  更靈活,但實現相對複雜。
8

流程解讀:

  • 1)連接初始化:客户端使用特定的 Content-Type: text/event-stream 向服務器發起一個普通的 HTTP GET 請求。服務器確認並保持連接開放。
  • 2)數據推送:服務器通過保持打開的連接,以純文本格式(遵循 data: ...、event: ... 等規範)持續發送數據塊。每個消息以兩個換行符 \n\n 結束。
  • 3)連接容錯:如果連接因網絡問題中斷,SSE 客户端內置的機制會自動嘗試重新建立連接,極大地提高了應用的魯棒性。
  • 4)客户端處理:瀏覽器端的 EventSource API 會解析收到的數據流,觸發相應的事件(如 onmessage 或自定義事件),讓開發者能夠處理推送來的數據。

SSE 的誕生是 Web 開發對簡單、高效、標準化的服務器推送技術需求的直接結果。它有效地替代了笨拙的輪詢技術,在與 WebSocket 的競爭中,找到了自身在單向數據流場景下的獨特定位。

其發展歷程經歷了從概念提出、瀏覽器支持到成為正式標準的完整路徑。儘管曾受限於 IE,但在現代瀏覽器中已成為一項穩定、可靠且被廣泛採用的技術。如今,在實時通知、金融儀表盤、實時日誌跟蹤和大型語言模型(LLM)的流式響應輸出等場景中,SSE 都是首選的解決方案。

7、默默無聞的SSE為何在AI大模型時代一夜爆火?

SSE 最近站到聚光燈下,幾乎可以説最大的推手就是當前 AI 應用(尤其是 ChatGPT 等大型語言模型)的爆發式增長。SSE  之所以成為 AI 應用的“標配”,是因為 SSE 與  AI 所需的“打字機” 輸出模式  是 天作之合。

7.1 什麼是AI大模型“打字機” 式的逐token輸出?

“打字機”式 逐 token 輸出是一種流式傳輸方式,它模擬了人類打字或思考的過程。

服務器不是等待 LLM 生成整個答案 後一次性發送給 用户,而是 流式輸出, 每生成一個“詞元”(token,可以粗略理解為一個詞或一個字),就立刻發送這個“詞元”。

下面舉一個例子,對比 一下  傳統方式(非流式)和 “打字機” (流式)式 的過程。

傳統方式(非流式)過程如下:

  • 1)你提問:“請寫一首關於春天的詩”。
  • 2)服務器端的 AI 開始思考、生成,整個過程你需要等待(可能好幾秒甚至更久)。
  • 3)AI 生成完整的詩歌:“春風拂面綠意濃,百花爭豔映晴空...”。
  • 4)服務器將整首詩作為一個完整的 JSON 對象 { "content": "春風拂面綠意濃,百花爭豔映晴空..." } 發送給客户端。
  • 5)客户端一次性收到全部內容並渲染出來。

“打字機”(流式)過程如下:

  • 1)你提問:“請寫一首關於春天的詩”。
  • 2)服務器端的 AI 生成第一個 token “春”,立刻通過 SSE 發送 data: “春”。
  • 3)客户端收到“春”並顯示出來。
  • 4)AI 生成第二個 token “風”,立刻發送 data: “風”。
  • 5)客户端在“春”後面追加“風”,形成“春風”。
  • 6)後續 token “拂”、“面”、“綠”、“意”、“濃”... 依次迅速發送和追加。
  • 7)你看到的效果就是文字一個接一個地“打”在屏幕上,就像有人在遠端為你實時打字一樣。

“打字機”(流式) 模式的巨大優勢:

  • 1)極低的感知延遲:用户幾乎在提問後瞬間就能看到第一個字開始輸出,無需經歷漫長的等待白屏期,體驗流暢自然。
  • 2)提供了“正在進行”的反饋:看着文字逐個出現,給人一種模型正在為你“思考”和“創作”的生動感,而不是在“沉默中宕機”。
  • 3)更高效地利用時間:用户可以在前半句還在輸出時,就開始閲讀和理解,節省了總體的認知時間。

7.2 為什麼SSE跟AI大模型是“天作之合”?

這正是 SSE 的設計初衷和核心優勢所在,它與 AI 流式輸出的需求完美匹配。

1)單向通信的完美匹配:

AI 的文本生成過程本質上是服務器到客户端的單向數據推送。客户端只需要接收,不需要在生成過程中頻繁地發送請求。SSE 的“服務器推送”模型正是為此而生,而 WebSocket 的雙向能力在這裏是多餘的。

2)基於 HTTP/HTTPS,簡單且兼容:

SSE 使用標準的 HTTP 協議,這意味着  SSE 易於實現和調試:任何後端框架和前端語言都能輕鬆處理。在瀏覽器中調試時,你可以在“網絡”選項卡中直接看到以文本流形式傳輸的事件,非常直觀。

SSE 使用標準的 HTTP 協議,這還意味着  容易繞過網絡障礙:公司防火牆和代理通常對 HTTP/HTTPS 放行,而可能會阻攔陌生的 WebSocket 協議。這使得 SSE 的部署兼容性極好。

3)內置的自動重連機制:

網絡連接並不完全可靠。如果用户在接收很長的回答時網絡波動,連接中斷,SSE 客户端會自動嘗試重新連接。這對於長時間流的應用至關重要,提供了天然的魯棒性。

4)輕量級的文本協議:

AI 流式輸出傳輸的就是文本(UTF-8編碼)。SSE 的協議 data: ...\n\n 就是為傳輸文本片段而設計的,極其高效和簡單。WebSocket 雖然也能傳文本,但其協議設計還考慮了二進制幀、掩碼等更復雜的情況,對於純文本流來説顯得有些“重”。

5)原生瀏覽器 API:

現代瀏覽器都原生支持 EventSource API,開發者無需引入額外的第三方庫,即可輕鬆實現接收流式數據,減少了依賴和打包體積。

9

所以,SSE 站到聚光燈下的原因正是:

AI 應用需要“打字機”式的逐 token 輸出體驗,而 SSE 作為一種基於 HTTP 的、簡單的、單向的服務器推送技術,是實現這種體驗最自然、最高效、最可靠的技術選擇。

它就像是為這個場景量身定做的工具,沒有多餘的功能,只有恰到好處的設計。因此,當 ChatGPT 等應用席捲全球時,其背後默默無聞的 SSE 技術也終於從幕後走到了台前,被廣大開發者所重新認識和重視。

8、SSE的技術原理詳解

8.1 工作機制的流程圖

SSE 通過一個持久的 HTTP 連接實現服務器到客户端的單向數據流。

以下是其工作機制的流程圖:

10

 

以下是關鍵步驟解析。

1)瀏覽器發起一個 HTTP 請求,Header 中包含:

1Accept: text/event-stream

2)服務器響應類型必須為:

Content-Type: text/event-stream

Cache-Control: no-cache

Connection: keep-alive

3)服務器發送事件格式(每個事件以兩個換行符結束):

event: message

data: {"time": "2023-10-05T12:00:00", "value": "New update!"}

id: 12345

retry: 5000

\n\n

4)瀏覽器通過 EventSourceAPI 接收並處理事件。

5)服務器發送 一個特殊“結束”事件,可以結束傳輸。比如,服務器發送一個如 event: end 的消息,可以結束傳輸。客户端預先監聽這個自定義的 end 事件,一旦收到,就知道傳輸結束,並可以選擇主動關閉 EventSource 連接。

6)若連接中斷,瀏覽器會根據 retry字段自動重連。如果沒有收到  特殊“結束”事件, 瀏覽器 可以自動重連。

8.2 SSE與其他通信方式對比

不同通信技術各有適用場景,我們用表格清晰對比:

11

 

8.3 SSE的適用場景

1)ChatGPT 式逐字輸出( “打字機” 式逐 詞元 token輸出):

12

 

2)實時通知系統:

  • a. 新訂單提醒;
  • b. 用户消息推送;
  • c. 審核狀態更新。

3)實時數據看板:

  • a. 股票行情;
  • b. 設備監控數據;
  • c. 實時日誌流。

9、SSE客户端API詳解

SSE的客户端實現非常簡單,瀏覽器原生提供了EventSource對象來處理與服務器的SSE連接。下面我們詳細介紹它的使用方法和核心特性。

9.1 認識瀏覽器端EventSource對象

瀏覽器兼容性檢測:

在使用SSE前,首先需要確認當前瀏覽器是否支持EventSource(除IE/Edge外,幾乎所有現代瀏覽器都支持)。

檢測方法如下:

// 檢查瀏覽器是否支持SSE

if ('EventSource' in window) {

  // 支持SSE,可正常使用

  console.log('瀏覽器支持SSE');

} else {

  // 不支持SSE,需降級處理

  console.log('瀏覽器不支持SSE');

}

創建連接:

使用EventSource創建與服務器的連接非常簡單,只需傳入服務器的SSE接口地址:

// 建立與服務器的SSE連接

// url為服務器提供的SSE接口地址(可同域或跨域)

var source = new EventSource(url);

如果需要跨域請求並攜帶Cookie,可通過第二個參數配置:

// 跨域請求時,允許攜帶Cookie

var source = new EventSource(url, {

  withCredentials: true // 默認為false,設為true表示跨域請求攜帶Cookie

});

連接狀態(readyState):

EventSource實例的readyState屬性用於表示當前連接狀態,只讀且有三個可能值:

13

 

可以通過該屬性判斷當前連接狀態,例如:

if (source.readyState === EventSource.OPEN) {

  console.log('SSE連接已正常建立');

}

9.2 基本使用方法

EventSource通過事件機制處理連接過程中的各種狀態和接收的數據,核心事件包括open、message、error。

下面用流程圖展示SSE客户端的完整使用流程:

14

連接建立:open事件

當客户端與服務器成功建立SSE連接時,會觸發open事件:

// 方式1:使用onopen屬性

source.onopen = function (event) {

  console.log('SSE連接已建立');

  // 可在此處做連接成功後的初始化操作,如更新UI狀態

};

// 方式2:使用addEventListener(推薦,可添加多個回調)

source.addEventListener('open', function (event) {

  console.log('SSE連接已建立(監聽方式)');

}, false);

接收數據:message事件

當客户端收到服務器推送的數據時,會觸發message事件(默認事件,處理未指定類型的消息):

// 方式1:使用onmessage屬性

source.onmessage = function (event) {

  // event.data為服務器推送的文本數據

  var data = event.data;

  console.log('收到數據:', data);

  // 可在此處處理數據,如更新頁面內容

};

// 方式2:使用addEventListener

source.addEventListener('message', function (event) {

  var data = event.data;

  console.log('收到數據(監聽方式):', data);

}, false);

注意:event.data始終是字符串類型,如果服務器發送的是JSON數據,需要用JSON.parse(data)轉換。

連接錯誤:error事件

當連接發生錯誤(如網絡中斷、服務器出錯)時,會觸發error事件:

// 方式1:使用onerror屬性

source.onerror = function (event) {

  // 可根據readyState判斷錯誤類型

  if (source.readyState === EventSource.CONNECTING) {

    console.log('連接出錯,正在嘗試重連...');

  } else {

    console.log('連接已關閉,無法重連');

  }

};

// 方式2:使用addEventListener

source.addEventListener('error', function (event) {

  // 錯誤處理邏輯

}, false);

關閉連接:close()方法

如果需要主動關閉SSE連接(關閉後不會自動重連),可調用close()方法:

// 主動關閉SSE連接

source.close();

console.log('SSE連接已手動關閉');

9.3 自定義事件

默認情況下,服務器推送的消息會觸發message事件。但實際開發中,我們可能需要區分不同類型的消息(如"新訂單通知"和"系統公告"),這時就可以使用自定義事件。

客户端通過addEventListener監聽自定義事件名,例如監聽order事件:

// 監聽名為"order"的自定義事件

source.addEventListener('order', function (event) {

  var orderData = event.data;

  console.log('收到新訂單:', orderData);

  // 處理訂單相關邏輯

}, false);

// 再監聽一個名為"notice"的自定義事件

source.addEventListener('notice', function (event) {

  var noticeData = event.data;

  console.log('收到系統公告:', noticeData);

  // 處理公告相關邏輯

}, false);

注意:自定義事件不會觸發message事件,只會被對應的addEventListener捕獲。

上面代碼中,瀏覽器對 SSE 的foo``notice事件進行監聽。如何實現服務器發送foo``notice事件,請看下文。

10、SSE服務器端技術詳解

服務器要實現SSE,核心是按照特定格式向客户端發送數據。下面詳細介紹服務器端的實現規範。

10.1 HTTP 頭信息要求

服務器向客户端發送SSE數據時,必須設置以下HTTP響應頭,否則客户端無法正確識別為事件流:

Content-Type: text/event-stream // 必須,指定為事件流類型

Cache-Control: no-cache // 必須,禁止緩存,確保數據實時性

Connection: keep-alive // 必須,保持長連接

這三個頭信息是SSE的基礎,缺少任何一個都可能導致連接失敗或數據異常。

10.2 數據傳輸格式

服務器發送的每條消息(message)由多行組成,每行格式為[字段]: 值\n(字段名後必須跟冒號和空格,結尾用換行符\n)。多條消息之間用\n\n(兩個換行符)分隔。

此外,以 : 開頭的行是註釋(服務器可定期發送註釋保持連接)。

基本格式示例:

: 這是一條註釋(客户端會忽略)\n

data: 這是第一條消息\n\n

data: 這是第二條消息的第一行\n

data: 這是第二條消息的第二行\n\n

注意:換行符必須是\n(Unix格式),\r\n可能導致客户端解析錯誤。

10.3 核心字段説明

SSE消息支持四個核心字段,分別用於不同場景。

1)data字段:消息內容:

data字段用於攜帶實際的消息內容,是最常用的字段。

單行數據:

  data: Hello, SSE!\n\n // 單行數據,以\n\n結束

多行數據(適合JSON等複雜結構):

  data: {\n // 第一行以\n結束

  data: "name": "張三",\n // 第二行以\n結束

  data: "age": 20\n // 第三行以\n結束

  data: }\n\n // 最後一行以\n\n結束

客户端接收後,event.data會自動拼接為完整字符串:{"name": "張三","age": 20}

2)event字段:指定事件類型:

event字段用於指定消息的事件類型,客户端可通過對應事件名監聽(即9.3節的自定義事件)。

服務器發送:

event: order\n // 指定事件類型為order

data: 新訂單ID:12345\n // 消息內容

\n // 消息結束(\n\n簡化為單獨一行)

客户端監聽:

source.addEventListener('order', function(event) {

  console.log(event.data); // 輸出:新訂單ID:12345

});

3)id字段:消息標識:

id字段用於給消息設置唯一標識,客户端會自動記錄最後一條消息的id(存於source.lastEventId)。

核心作用:當連接斷線重連時,客户端會在請求頭中攜帶Last-Event-ID: [最後收到的id],服務器可根據該ID恢復數據傳輸(避免重複或丟失)。

服務器發送:

id: msg1001\n // 消息標識

data: 這是第1001條消息\n

\n

客户端重連時的請求頭:

Last-Event-ID: msg1001 // 自動攜帶最後收到的id

4)retry字段:重連間隔:

retry字段用於指定客户端斷線後的重連間隔(單位:毫秒),默認重連間隔約為3秒。

服務器發送:

retry: 5000\n // 告訴客户端,斷線後5秒再重連

data: 重連間隔已設置為5秒\n

\n

5)服務器保持連接示例:

服務器可以定期發送註釋行,保持連接活躍:

: 這是保持連接活動的註釋行\n

: 服務器時間 2023-10-05T12:00:00\n

10.4 服務器發送流程

服務器發送SSE數據的完整流程如下:

15

 

下面是一個包含多種字段的服務器發送示例,模擬一個實時通知系統:

: 服務器開始發送消息(註釋)\n

id: 1001\n

event: notice\n

data: 系統將在10分鐘後維護\n\n

id: 1002\n

event: order\n

data: {"orderId": "20230501", "status": "paid"}\n\n

retry: 10000\n

id: 1003\n

data: 重連間隔已調整為10秒\n\n

: 這是保持連接活動的註釋行\n

: 服務器時間 2023-10-05T12:00:00\n

客户端接收後:

  • 1)notice事件會捕獲到"系統將在10分鐘後維護"
  • 2)order事件會捕獲到訂單JSON數據
  • 3)重連間隔被設置為10秒
  • 4)最後收到的消息ID是1003(斷線重連時會攜帶)

通過以上規範,服務器就能輕鬆實現SSE功能,向客户端實時推送數據。相比WebSocket,SSE的服務器實現更簡單,無需處理複雜的協議握手,只需按格式發送文本數據即可。

11、SSE實戰代碼示例(基於Spring Boot的實時通信)

接下來, 通過一個完整案例  手把手教你用Spring Boot實現SSE功能。這個案例包含服務端(後端)和客户端(前端)代碼, 可以直接運行體驗服務器主動推送數據的效果。

11.1 案例整體架構

我們要實現的系統包含三個核心部分:

  • 1)後端服務:基於Spring Boot,提供SSE連接接口、消息廣播接口和任務進度推送接口;
  • 2)前端頁面:一個簡單的HTML頁面,通過EventSource與後端建立SSE連接;
  • 3)交互流程:客户端連接後,可接收服務器主動推送的連接狀態、廣播消息和任務進度。

整體架構流程圖:

16

11.2 服務端實現

11.2.1)準備依賴:

首先創建Spring Boot項目,在pom.xml中添加以下依賴(用於web開發和頁面渲染):

<dependencies>

    <!-- Spring Web:提供SSE相關類和HTTP服務 -->

    <dependency>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-web</artifactId>

    </dependency>

    <!-- Thymeleaf:用於渲染前端頁面 -->

    <dependency>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-thymeleaf</artifactId>

    </dependency>

</dependencies>

這些依賴是基礎:spring-boot-starter-web提供了SSE核心類SseEmitter,spring-boot-starter-thymeleaf用於將HTML頁面返回給瀏覽器。

11.2.2)編寫SSE核心控制器:

創建SseController,這是服務端處理SSE連接和消息推送的核心類:

package com.example.sse.controller;

import org.springframework.http.MediaType;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RequestParam;

import org.springframework.web.bind.annotation.RestController;

import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;

import java.util.concurrent.CopyOnWriteArrayList;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

@RestController

public class SseController {

    // 存儲所有活躍的SSE連接(線程安全的列表)

    // CopyOnWriteArrayList適合讀多寫少場景,避免併發問題

    private final CopyOnWriteArrayList emitters = new CopyOnWriteArrayList<>();

    // 線程池:用於異步發送事件,避免阻塞主線程

    private final ExecutorService executor = Executors.newCachedThreadPool();

    /

     * 客户端訂閲SSE的接口

     * 客户端通過訪問該接口建立長連接,接收服務器推送的事件

     */

    @GetMapping(value = "/sse/subscribe", produces = MediaType.TEXT_EVENT_STREAM_VALUE)

    public SseEmitter subscribe() {

        // 創建SseEmitter實例,設置超時時間為無限(默認30秒會超時,這裏設為Long.MAX_VALUE避免自動斷開)

        SseEmitter emitter = new SseEmitter(Long.MAX_VALUE);

        // 將新連接加入活躍列表(後續推送消息時會遍歷這個列表)

        emitters.add(emitter);

        // 設置連接完成/超時的回調:從活躍列表中移除該連接,釋放資源

        emitter.onCompletion(() -> emitters.remove(emitter)); // 連接正常關閉時

        emitter.onTimeout(() -> emitters.remove(emitter)); // 連接超時關閉時

        // 發送初始連接成功消息(給客户端的"歡迎消息")

        try {

            emitter.send(SseEmitter.event()

                    .name("CONNECTED") // 事件名稱:客户端可通過"CONNECTED"事件監聽

                    .data("You are successfully connected to SSE server!") // 消息內容

                    .reconnectTime(5000)); // 告訴客户端:如果斷開連接,5秒後重連

        } catch (IOException e) {

            // 發送失敗時,標記連接異常結束

            emitter.completeWithError(e);

        }

        return emitter; // 將emitter返回給客户端,保持連接

    }

    /

     * 廣播消息接口:向所有已連接的客户端推送消息

     * 可通過瀏覽器訪問 http://localhost:8080/sse/broadcast?message=xxx 觸發

/

    @GetMapping("/sse/broadcast")

    public String broadcastMessage(@RequestParam String message) {

        // 用線程池異步執行廣播,避免阻塞當前請求

        executor.execute(() -> {

            // 遍歷所有活躍連接,逐個發送消息

            for (SseEmitter emitter : emitters) {

                try {

                    emitter.send(SseEmitter.event()

                            .name("BROADCAST") // 事件名稱:客户端監聽"BROADCAST"事件

                            .data(message) // 廣播的消息內容

                            .id(String.valueOf(System.currentTimeMillis()))); // 消息ID(用於重連時定位)

                } catch (IOException e) {

                    // 發送失敗(可能客户端已斷開),從列表中移除並標記連接結束

                    emitters.remove(emitter);

                    emitter.completeWithError(e);

                }

            }

        });

        return "Broadcast message: " + message; // 給調用者的響應

    }

    /

     * 模擬長時間任務:向客户端推送實時進度

     * 適合文件上傳、數據處理等需要實時反饋進度的場景

/

    @GetMapping("/sse/start-task")

    public String startTask() {

        // 異步執行任務,避免阻塞當前請求

        executor.execute(() -> {

            try {

                // 模擬任務進度:從0%到100%,每次增加10%

                for (int i = 0; i <= 100; i += 10) {

                    Thread.sleep(1000); // 休眠1秒,模擬處理耗時

                    // 向所有客户端推送當前進度

                    for (SseEmitter emitter : emitters) {

                        try {

                            emitter.send(SseEmitter.event()

                                    .name("PROGRESS") // 事件名稱:客户端監聽"PROGRESS"事件

                                    .data(i + "% completed") // 進度數據

                                    .id("task-progress")); // 固定ID,標識這是任務進度消息

                        } catch (IOException e) {

                            // 發送失敗,移除連接

                            emitters.remove(emitter);

                        }

                    }

                    // 任務完成時,發送結束消息

                    if (i == 100) {

                        for (SseEmitter emitter : emitters) {

                            try {

                                emitter.send(SseEmitter.event()

                                        .name("COMPLETE") // 事件名稱:客户端監聽"COMPLETE"事件

                                        .data("Task completed successfully!"));

                            } catch (IOException e) {

                                emitters.remove(emitter);

                            }

                        }

                    }

                }

            } catch (InterruptedException e) {

                // 任務被中斷時,恢復線程中斷狀態並退出

                Thread.currentThread().interrupt();

                break;

            }

        });

        return "Task started!"; // 告訴調用者任務已啓動

    }

}

核心代碼説明:

  • 1)SseEmitter:Spring提供的SSE核心類,每個實例對應一個客户端連接;
  • 2)emitters列表:管理所有活躍連接,方便廣播消息(類似"客户端註冊表");
  • 3)executor線程池:異步處理消息發送,避免阻塞主線程(如果同步發送,一個客户端卡住會影響所有用户)。

事件發送:通過 emitter.send(SseEmitter.event()) 構建消息,可指定事件名、數據、ID和重連時間。

11.2.3)編寫頁面控制器:

創建PageController,用於將前端頁面返回給瀏覽器:

package com.example.sse.controller;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.GetMapping;

@Controller // 注意這裏用@Controller而非@RestController,用於返回頁面

public class PageController {

    /*

     * 訪問根路徑時,返回SSE客户端頁面

/

    @GetMapping("/")

    public String index() {

        // 返回src/main/resources/templates目錄下的sse-client.html

        return "sse-client";

    }

}

11.3 客户端實現(HTML頁面)

在 src/main/resources/templates 目錄下創建 sse-client.html,這是用户交互的前端頁面:

Server-Sent Events (SSE) Client   Connect to SSE                Disconnect                 Send Broadcast             Start Task  Messages:

客户端核心邏輯:

  • 1)eventSource:EventSource實例,是客户端與服務端SSE連接的"橋樑";
  • 2)事件監聽:通過addEventListener監聽服務端定義的事件(CONNECTED/BROADCAST等);
  • 3)自動重連:當連接斷開時,EventSource會自動重試(無需手動寫重連邏輯);
  • 4)交互函數:connectSSE/disconnectSSE等函數對應頁面按鈕,實現用户操作。

11.4 運行與測試

啓動步驟:

  • 1)確保Spring Boot項目配置正確(默認端口8080,無需額外配置);
  • 2)啓動Spring Boot應用(運行帶有main方法的啓動類);
  • 3)打開瀏覽器,訪問 http://localhost:8080/,看到客户端頁面。

功能測試:

  • 1)建立連接:點擊"Connect to SSE"按鈕,頁面會顯示"連接成功"的消息(服務端通過CONNECTED事件推送)
  • 2)發送廣播:點擊"Send Broadcast"按鈕,輸入任意消息(如"Hello SSE"),頁面會顯示廣播消息(服務端向所有連接的客户端推送)
  • 3)啓動任務:點擊"Start Task"按鈕,頁面會每秒收到一條進度消息(從0%到100%),最後顯示"任務完成"
  • 4)斷開連接:點擊"Disconnect"按鈕,連接關閉,不再接收消息。

測試流程圖:

17

 

11.5 服務端的關鍵技術點

1)SseEmitter的作用:Spring封裝的SSE工具類,簡化了"保持連接+發送事件"的實現,無需手動處理HTTP流格式。

2)連接管理:用CopyOnWriteArrayList存儲活躍連接,確保線程安全;通過onCompletion/onTimeout回調清理無效連接,避免內存泄漏。

3)異步處理:必須用線程池(ExecutorService)異步發送消息,否則會阻塞主線程,導致新請求無法處理。

4)事件設計:通過name區分不同類型的事件(如PROGRESS/BROADCAST),客户端按需監聽,邏輯更清晰。

5)自動重連:SSE客户端(EventSource)內置重連機制,網絡恢復後會自動重新連接,無需額外代碼。

通過這個案例,你可以清晰看到SSE的優勢:實現簡單(幾行代碼就能建立實時連接)、無需額外協議(基於HTTP)、自帶重連機制。如果你的場景只需要服務器單向推送數據(如實時通知、進度更新),SSE會是比WebSocket更輕量的選擇。

12、選SSE還是選WebSocket?

12.1 SSE與WebSocket全面對比

來對 Server-Sent Events (SSE) 和 WebSocket 進行一場全面、深入的對比。

18

為了更直觀地理解兩者的工作模式差異,請看下面的序列圖:

19

1)協議與連接建立:

SSE 協議與連接建立:

  • a. 基於純粹的 HTTP。客户端發起一個普通的 HTTP GET 請求,並攜帶特殊的頭 Accept: text/event-stream。
  • b. 服務器響應後,保持這個 TCP 連接打開,並開始發送數據流 ,直到遇到結束標記。
  • c. 這是一種長連接的 HTTP 用法。

WebSocket 協議與連接建立:

  • a. 基於獨立的 WebSocket 協議。連接始於一個特殊的 HTTP 請求,即 “協議升級”請求(Connection: Upgrade, Upgrade: websocket)。
  • b. 服務器響應 HTTP 101 Switching Protocols 後,最初的 HTTP 連接被替換為 WebSocket 連接,此後通信不再遵循 HTTP 協議,而是在其之上建立一個全雙工的通道。

2)數據流與通信模式:

SSE:單向通信。設計初衷就是讓服務器能夠主動、高效地向客户端推送數據。•數據是文本流,格式簡單且可讀性強。每條消息可以附帶一個事件類型(event:)和一個ID(id:)。•客户端使用 EventSource API 監聽來自服務器的事件。

WebSocket:全雙工通信。在連接建立後,客户端和服務器處於完全平等的地位,可以隨時、任意地相互發送消息。 另外,WS協議  支持文本和二進制數據,靈活性極高,非常適合需要頻繁雙向交互的場景(如遊戲、協作編輯)。

3)能力與特性:

SSE:內置自動重連機制。如果連接斷開,EventSource 對象會自動嘗試重新連接,並在重連後自動發送上一個收到的事件ID,服務器據此可判斷錯過了哪些消息,實現數據恢復。SSE有出色的瀏覽器支持。所有現代瀏覽器(Chrome, Firefox, Safari, Edge)都原生支持,Internet Explorer (古代瀏覽器)完全不支持(通常需要 polyfill 或降級方案)。

WebSocket:無自動重連。連接斷開後,需要開發者手動編寫重連邏輯和狀態恢復邏輯。WS協議比SSE協議有更廣泛的瀏覽器支持,包括 Internet Explorer 10+。

4)開發與集成:

SSE:開發與集成 非常簡單。服務器端幾乎不需要特殊的庫,任何能輸出 HTTP 流的後端語言都可以實現。客户端 API 也非常直觀。與現有 HTTP 認證、CORS 機制完全兼容,處理方式與普通 HTTP 請求一致。

WebSocket:開發與集成 相對複雜。服務器端需要支持 WebSocket 協議的庫(如 ws for Node.js, Socket.IO 等)。客户端需要處理連接狀態、心跳包等。 雖然升級握手是 HTTP,但後續通信是獨立協議,因此一些複雜的網絡環境(如某些代理服務器)可能會帶來問題。

12.2 SSE與WebSocket到底該如何選擇?

選擇的關鍵在於應用場景和核心需求。

* 選擇 SSE 的場景:

選擇 SSE 的場景包括:

  • 1)服務器到客户端的單向數據流。
  • 2)簡單和快速實現是關鍵因素。
  • 3)需要自動錯誤恢復(重連)。
  • 4)數據傳輸格式是文本(如 JSON),且不需要二進制。

SSE  典型的應用場景包括:

  • 1)實時新聞推送、體育比分更新。
  • 2)金融報價行情(如股票價格變動)。
  • 3)社交媒體動態更新(如 Twitter 時間線)。
  • 4)服務器日誌流監控。
  • 5)AI 處理進度或結果的流式輸出。

* 選擇 WebSocket 場景:

選擇 WebSocket 的場景包括:

  • 1)真正的實時雙向通信,客户端和服務器都需要頻繁地發送消息。
  • 2)需要傳輸二進制數據(如視頻、音頻、圖像碎片)。
  • 3)構建交互性極強的應用,其中低延遲至關重要。

WebSocket  典型的應用場景包括:

  • 1)實時在線聊天應用(如 Slack、Discord、RainbowChat-Web)。
  • 2)多人在線遊戲。
  • 3)協同編輯工具(如 Google Docs)。
  • 4)實時儀表盤和控制面板(需要雙向控制)。
20

12.3 WebSocket+SSE 混合架構

一般來説大型應用場景,強網用 WebSocket、弱網適合使用SSE ,這就是WebSocket+SSE 混合架構。強網用 WebSocket、弱網自動降級到 SSE 的混合架構, 核心在於網絡質量動態評估和雙通道無縫切換。

WebSocket+SSE 混合架構 具體實現方案如下:

21

 

核心模塊:網絡質量探針(客户端) 實現

class NetworkProbe {

  // 關鍵指標

  static RTT_THRESHOLD = 300 // RTT超過300ms視為弱網

  static PACKET_LOSS_THRESHOLD = 0.2 // 丟包率>20%觸發降級

  // 網絡狀態檢測

  async check() {

    const { rtt, packetLoss } = await this._measure()

    return {

      isWeak: rtt > NetworkProbe.RTT_THRESHOLD ||

              packetLoss > NetworkProbe.PACKET_LOSS_THRESHOLD

    }

  }

  // 實際測量方法

  _measure() {

    return new Promise(resolve => {

      const start = Date.now()

      fetch('/ping', { cache: 'no-store' })

        .then(() => {

          const rtt = Date.now() - start

          resolve({ rtt, packetLoss: 0 })

        })

        .catch(() => resolve({ rtt: Infinity, packetLoss: 1 }))

    })

  }

}

核心模塊:雙協議連接管理器(客户端)

class HybridConnection {

  constructor() {

    this.currentProtocol = null

    this.ws = null

    this.sse = null

    this.messageQueue = [] // 消息緩衝隊列

  }

  // 智能連接初始化

  async connect() {

    const { isWeak } = await new NetworkProbe().check()

    this.currentProtocol = isWeak ? 'sse' : 'ws'

    if (this.currentProtocol === 'ws') {

      this._initWebSocket()

    } else {

      this._initSSE()

    }

  }

  // WebSocket初始化

  _initWebSocket() {

    this.ws = new WebSocket('wss://api.example.com')

    this.ws.onmessage = this._handleMessage

    // 發送緩衝隊列消息

    this.messageQueue.forEach(msg => this.ws.send(msg))

    this.messageQueue = []

  }

  // SSE初始化

  _initSSE() {

    this.sse = new EventSource('https://api.example.com/sse')

    this.sse.onmessage = this._handleMessage

  }

  // 統一消息處理

  _handleMessage = (event) => {

    const data = event.data || event

    // 業務邏輯處理...

  }

  // 發送消息(自動選擇協議)

  send(data) {

    if (this.currentProtocol === 'ws' && this.ws?.readyState === 1) {

      this.ws.send(JSON.stringify(data))

    } else if (this.currentProtocol === 'sse') {

      // SSE需通過獨立HTTP請求發送

      fetch('/send', { method: 'POST', body: JSON.stringify(data) })

    } else {

      // 協議切換中暫存消息

      this.messageQueue.push(JSON.stringify(data))

    }

  }

  // 協議切換(核心!)

  async switchProtocol() {

    const { isWeak } = await new NetworkProbe().check()

    // 無需切換

    if (isWeak && this.currentProtocol === 'sse') return

    if (!isWeak && this.currentProtocol === 'ws') return

    // 執行切換

    if (isWeak) {

      this.ws?.close()

      this._initSSE()

      this.currentProtocol = 'sse'

    } else {

      this.sse?.close()

      this._initWebSocket()

      this.currentProtocol = 'ws'

    }

  }

}

12.4 AI大模型中該選擇SSE協議還是WebSocket?

直接答案:對於絕大多數 chat2ai 應用  優先選擇 SSE (Server-Sent Events)。複雜的  chat2ai 應用  優先選擇WebSocket。

但這並非絕對,我們需要根據具體的功能需求來決定。下面我將為你進行詳細的分析和推理。

12.4.1)核心決策分析:

AI聊天應用的核心交互是:

  • 1)客户端發送一條消息(一個問題)。
  • 2)服務器接收後,調用大語言模型(LLM)API。
  • 3)服務器將模型流式返回的答案(逐詞或逐句)實時推送給客户端。
  • 4)客户端實時渲染這個流式的答案,營造出“打字機”效果。

這個過程的關鍵在於第3步,即服務器向客户端的單向數據推送。這正是 SSE 的絕對主場。

12.4.2)為什麼 SSE 是更優的選擇?

以下流程圖清晰地展示了基於不同技術方案的聊天交互過程,其中突出了SSE方案的巨大優勢:

22

正如上圖所示:SSE 方案在實現上更加直接和高效,因為它基於 HTTP,並且專門為服務器到客户端的單向數據流設計。

此外,SSE 還帶來了以下巨大優勢:

1)開發複雜度極低:  

  • a. 後端:你不需要引入任何複雜的 WebSocket 庫(如 ws, Socket.IO)。你只需要建立一個普通的 HTTP 路由(如 POST /chat 用於發送消息,GET /chat/stream 用於接收流),並在控制器中輸出 text/event-stream 格式的響應流。
  • b. 前端:使用瀏覽器原生的 EventSource API 即可輕鬆監聽數據流,幾行代碼就能實現。無需實例化和管理 WebSocket 連接對象。

2)出色的兼容性與可維護性:

  • a. SSE 基於 HTTP,這意味着它更容易通過公司防火牆、代理,與現有的認證系統(如 Cookie、JWT)、CORS 策略協同工作,幾乎不會遇到奇怪的網絡問題。
  • b. 在瀏覽器“網絡”選項卡中,SSE 的流清晰可見,易於調試。每個消息都是可讀的文本,調試體驗非常好。

3)內置的自動重連與斷點續傳機制:

  • a. 這是 SSE 的“殺手級特性”。網絡連接不穩定是移動端的常見問題。如果用户在接收一個很長答案的過程中網絡中斷,SSE 會在網絡恢復後自動重新連接。
  • b. 更強大的是,SSE 協議支持發送最後一個消息的 ID。服務器可以識別出這個 ID,並判斷客户端錯過了哪些數據,從而從斷點處繼續發送,而不是重新開始生成整個回答。這既節省了昂貴的 API 調用費用,也提升了用户體驗。這在 WebSocket 中需要手動實現所有邏輯,非常複雜。

12.4.3)WebSocket 的適用場景:

雖然 SSE 是主流選擇,但在 chat2ai 應用變得非常複雜時,WebSocket 可能會成為更好的選擇。

在以下情況下, 應該考慮使用 WebSocket:

1)需要極高頻的雙向通信:不僅僅是用户提問->AI回答。例如:

  • a. 實時協作編輯:多個用户同時編輯一份由 AI 生成的文檔,每個人的輸入都需要實時同步給其他所有人。
  • b. AI多人遊戲:基於 AI 生成劇情和環境的實時互動遊戲,玩家的每一個動作都需要實時影響虛擬世界。

2)當需要傳輸二進制數據的時候:有的聊天應用不僅支持文本,還支持實時語音對話(客户端錄音發送二進制音頻流,服務器返回 AI 語音二進制流)。WebSocket 對二進制數據的支持是天生的。

3)你需要非常精確的控制心跳和連接狀態:   - WebSocket 允許 手動發送 Ping/Pong 幀來檢測連接活性,雖然複雜,但給了開發人員最大的控制權。

12.4.4)傳輸協議選型 結論與建議:

1)起步和絕大多數情況:從 SSE 開始。這是最直接、最高效、最能給你帶來穩定體驗的選擇。使用sse 遇到的技術挑戰會更少,開發速度更快。ChatGPT、Claude 等絕大多數頂級應用都使用 SSE 不是沒有道理的。

2)未來如果需要擴展:採用混合架構。如果應用未來需要加入上述 WebSocket 的適用功能(如實時語音),完全可以同時使用兩種協議:使用 SSE 專門處理 AI 文本答案的流式推送。使用 WebSocket 專門處理 實時語音、實時協作等真正的雙向通信功能。或者 強弱結合,自動切換。

因此,對於  chat2ai 的傳輸協議選型答案是:優先選擇 SSE。

 

13、參考資料

[0] EventSource API Docs

[1] Web端即時通訊技術盤點:短輪詢、Comet、Websocket、SSE

[2] SSE技術詳解:一種全新的HTML5服務器推送事件技術

[3] 使用WebSocket和SSE技術實現Web端消息推送

[4] 詳解Web端通信方式的演進:從Ajax、JSONP 到 SSE、Websocket

[5] 使用WebSocket和SSE技術實現Web端消息推送

[6] 一文讀懂前端技術演進:盤點Web前端20年的技術變遷史

[7] WebSocket從入門到精通,半小時就夠!

[8] 網頁端IM通信技術快速入門:短輪詢、長輪詢、SSE、WebSocket

[9] 搞懂現代Web端即時通訊技術一文就夠:WebSocket、socket.io、SSE

[10] 大模型時代多模型AI網關的架構設計與實現

[11] 全民AI時代,大模型客户端和服務端的實時通信到底用什麼協議?

[12] 通俗易懂:AI大模型基於SSE的實時流式響應技術原理和實踐示例

[13] Web端實時通信技術SSE在攜程機票業務中的實踐應用

[14] ChatGPT如何實現聊天一樣的實時交互?快速讀懂SSE實時“推”技術

即時通訊技術學習:

- 移動端IM開發入門文章:《新手入門一篇就夠:從零開發移動端IM》

- 開源IM框架源碼:https://github.com/JackJiang2011/MobileIMSDK(備用地址點此)

(本文已同步發佈於:http://www.52im.net/thread-4885-1-1.html)

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.