SpringBoot-模擬SSE對話交互

SpringBoot-模擬SSE對話交互

后端使用SSE進行會話,前端使用Html模擬大模型的問答交互->【前端】+【后端】


1-學習目的

本項目代碼倉庫:https://gitee.com/enzoism/springboot_sse

1-核心知識點

  • 1)什么是SSE協議->客戶端發起一次請求,服務器保持該連接打開,并在有新數據時主動向客戶端推送
  • 2)后端-開發SSE控制器
  • 3)前端-如何與SSE協議交互

2-附帶知識點

  • 1)什么是請求跨域-后端如何解決跨域問題

2-動手實踐

1-什么是SSE協議

SSE(Server-Sent Events)協議是一種用于在 Web 瀏覽器和服務器之間實現服務器向客戶端單向實時通信的技術。下面將從多個方面詳細介紹 SSE 協議:

1-基本概念

SSE 允許服務器在建立連接后,持續向客戶端發送更新信息。與傳統的請求 - 響應模式不同,在 SSE 中,客戶端發起一次請求,服務器保持該連接打開,并在有新數據時主動向客戶端推送。

2-工作原理
  1. 建立連接:客戶端通過創建一個 EventSource 對象來向服務器發起 HTTP 請求,請求的響應頭中包含 Content-Type: text/event-stream,表明這是一個 SSE 連接。
  2. 服務器推送數據:服務器保持連接打開,并在有新數據時,以特定的格式將數據發送給客戶端。數據以文本流的形式傳輸,每條消息以兩個換行符 \n\n 分隔。
  3. 客戶端接收數據:客戶端的 EventSource 對象會監聽服務器發送的消息,并在接收到消息時觸發相應的事件。
3-消息格式

SSE 消息由多個字段組成,每個字段以鍵值對的形式表示,字段之間用換行符分隔。常見的字段有:

  • data:表示消息的實際內容。如果消息內容較長,可以分成多行,每行以 data: 開頭。
  • event:可選字段,用于指定事件類型。如果指定了事件類型,客戶端可以針對不同的事件類型進行不同的處理。
  • id:可選字段,用于為消息指定一個唯一的標識符。客戶端可以使用這個標識符來實現消息的斷點續傳。
  • retry:可選字段,用于指定客戶端在連接中斷后重試連接的時間間隔(以毫秒為單位)。
4-優點和缺點
  • 優點
    • 簡單易用:客戶端只需要創建一個 EventSource 對象,服務器端只需要按照特定的格式發送數據即可。
    • 自動重連:當連接中斷時,客戶端會自動嘗試重新連接,并且可以使用 id 字段實現消息的斷點續傳。
    • 瀏覽器原生支持:現代瀏覽器都原生支持 EventSource 對象,無需額外的庫或插件。
  • 缺點
    • 單向通信:SSE 只支持服務器向客戶端單向通信,客戶端不能向服務器發送消息。
    • 兼容性問題:雖然現代瀏覽器都支持 SSE,但在一些舊版本的瀏覽器中可能不支持。
    • 連接數量限制:瀏覽器對每個域名的 SSE 連接數量有一定的限制,通常為 6 個。
5-應用場景
  • 實時新聞推送:服務器可以實時向客戶端推送最新的新聞消息。
  • 股票行情更新:服務器可以實時向客戶端推送股票價格的變化。
  • 在線聊天系統:服務器可以實時向客戶端推送新的聊天消息。

2-后端-開發SSE控制器-Java版本

1. 編寫SSE控制器
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.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;@RestController
public class ChatController {private final DeepSeekService deepSeekService;public ChatController(DeepSeekService deepSeekService) {this.deepSeekService = deepSeekService;}@GetMapping("/chat")public SseEmitter chat(@RequestParam String message) {SseEmitter emitter = new SseEmitter();ExecutorService executorService = Executors.newSingleThreadExecutor();executorService.submit(() -> {try {// 調用DeepSeek的chat模型deepSeekService.streamChatResponse(message, emitter);} catch (Exception e) {emitter.completeWithError(e);} finally {executorService.shutdown();}});return emitter;}
}
2. 模擬DeepSeek服務
import org.springframework.stereotype.Service;@Service
public class DeepSeekService {public void streamChatResponse(String message, SseEmitter emitter) {// 調用DeepSeek的API并流式輸出try {// 模擬流式輸出String[] responses = {"Hello! ", "How can I help you? ", "I'm an AI assistant."};for (String response : responses) {emitter.send(SseEmitter.event().data(response));Thread.sleep(1000); // 模擬延遲}} catch (Exception e) {emitter.completeWithError(e);}}
}

3-前端:簡單的HTML/JavaScript界面

1. 創建一個前端頁面
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>DeepSeek Chat</title><style>body { font-family: Arial, sans-serif; margin: 20px; }#messageInput { width: 300px; padding: 5px; }#response { width: 400px; height: 200px; border: 1px solid #ccc; padding: 10px; }</style>
</head>
<body><h1>DeepSeek Chat</h1><input type="text" id="messageInput" placeholder="Enter your message"><button onclick="sendMessage()">Send</button><div id="response"></div><script>let eventSource;function sendMessage() {const messageInput = document.getElementById('messageInput');const responseDiv = document.getElementById('response');const message = messageInput.value;if (message.trim() === '') return;responseDiv.innerHTML = '';// 創建一個新的EventSourceeventSource = new EventSource(`/chat?message=${encodeURIComponent(message)}`);eventSource.onmessage = function (event) {responseDiv.innerHTML += event.data;};eventSource.onerror = function (error) {console.error('EventSource error:', error);eventSource.close();};}</script>
</body>
</html>

3-其他版本SSE-NodeJs

1-服務器端代碼示例(Node.js + Express)

const express = require('express');
const app = express();app.get('/sse', (req, res) => {res.setHeader('Content-Type', 'text/event-stream');res.setHeader('Cache-Control', 'no-cache');res.setHeader('Connection', 'keep-alive');res.flushHeaders();let counter = 0;const intervalId = setInterval(() => {res.write(`data: Message ${counter}\n\n`);counter++;}, 1000);req.on('close', () => {clearInterval(intervalId);});
});const port = 3000;
app.listen(port, () => {console.log(`Server running on port ${port}`);
});

2-客戶端代碼示例(JavaScript)

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8">
</head><body><div id="messages"></div><script>const eventSource = new EventSource('/sse');eventSource.onmessage = function (event) {const messagesDiv = document.getElementById('messages');const newMessage = document.createElement('p');newMessage.textContent = event.data;messagesDiv.appendChild(newMessage);};eventSource.onerror = function (error) {console.error('EventSource failed:', error);};</script>
</body></html>

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/72491.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/72491.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/72491.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2025 ubuntu24.04系統安裝docker

1.查看ubuntu版本&#xff08;Ubuntu 24.04 LTS&#xff09; rootmaster:~# cat /etc/os-release PRETTY_NAME"Ubuntu 24.04 LTS" NAME"Ubuntu" VERSION_ID"24.04" VERSION"24.04 LTS (Noble Numbat)" VERSION_CODENAMEnoble IDubun…

Avalonia 中文亂碼

代碼字體文件設置成支持中文的&#xff0c;但是編譯的代碼還是顯示的亂碼&#xff0c;原因是代碼文件的文件編碼格式不支持中文導致的。 如下面的2個頁面一部分中文顯示正常&#xff0c;一部分顯示正常&#xff0c;一部分顯示亂碼。

國產編輯器EverEdit - 工具欄自定義及認識工具欄上的按鈕

1 設置-高級-工具條 1.1 設置說明 1.1.1 工具條自定義 選擇主菜單工具 -> 設置 -> 常規&#xff0c;在彈出的選項窗口中選擇工具條分類&#xff0c;如下圖所示&#xff1a; 左側窗口是當前支持所有功能按鈕列表(上圖中居中欄)&#xff0c;右側的窗口是當前顯示在工具欄…

淘寶商品詳情高級版API接口測試與數據處理指南

在電商數據分析、商品監控和自動化運營中&#xff0c;淘寶商品詳情API接口是不可或缺的工具之一。本文將詳細介紹如何測試淘寶商品詳情高級版API接口的返回數據&#xff0c;并提供完整的數據處理流程&#xff0c;幫助開發者高效利用接口數據。 一、淘寶商品詳情API接口概述 淘…

C++海康相機DEMO

非標設備經常用到相機算法&#xff0c;利用工作之余時間&#xff0c;結合海康相機demo寫一套全面的相機應用&#xff0c;圖像處理常用的有halcon 、 opencv &#xff0c; MIL &#xff0c; visionpro&#xff0c;這里采用目前比較常用的halcon和opencv對相機圖片算法處理。整個…

TMS320F28P550SJ9學習筆記2:Sysconfig 配置與點亮LED

今日學習使用Sysconfig 對引腳進行配置&#xff0c;并點亮開發板上的LED4 與LED5 我的單片機開發板平臺是 LAUNCHXL_F28P55x 我是在上文描述的驅動庫C2000ware官方例程example的工程基礎之上進行添加功能的 該例程路徑如下&#xff1a;D:\C2000Ware_5_04_00_00\driverlib\f28p…

人機交互革命:從觸屏到腦波的13維戰爭

人機交互革命&#xff1a;從觸屏到腦波的13維戰爭 一、交互維度大爆炸&#xff1a;重新定義人機溝通邊界 當ChatGPT開始解析你的微表情&#xff0c;當Neuralink芯片能讀取皮層信號&#xff0c;人機交互已突破【鍵鼠】的次元壁。我們正經歷人類史上最大規模的感官革命&#xff…

使用Qt調用HslCommunication(C++調用C#庫)

使用C/CLI 來調用C#的dll 任務分解&#xff1a; 1、實現C#封裝一個調用hsl的dll&#xff1b; 2、實現C控制臺調用C#的dll庫&#xff1b; 3、把調用C#的dll用C再封裝為一個dll&#xff1b; 4、最后再用Qt調用c的dll&#xff1b; 填坑&#xff1a; 1、開發時VS需要安裝CLI項目庫…

maven高級-03.繼承與聚合-版本鎖定

一.版本鎖定 在maven中&#xff0c;父工程的pom文件中通過<dependencyManagement>來統一管理依賴的版本。 注意&#xff1a; <dependencyManagement>僅僅管理依賴的版本號&#xff0c;并不進行依賴的注入。如果要進行依賴注入還是要使用<dependencies>注解。…

基于opencv消除圖片馬賽克

以下是一個基于Python的圖片馬賽克消除函數實現&#xff0c;結合了圖像處理和深度學習方法。由于馬賽克消除涉及復雜的圖像重建任務&#xff0c;建議根據實際需求選擇合適的方法&#xff1a; import cv2 import numpy as np from PIL import Imagedef remove_mosaic(image_pat…

深入解析/etc/hosts.allow與 /etc/hosts.deny:靈活控制 Linux 網絡訪問權限

文章目錄 深入解析/etc/hosts.allow與 /etc/hosts.deny&#xff1a;靈活控制 Linux 網絡訪問權限引言什么是 TCP Wrappers&#xff1f;工作原理 什么是 /etc/hosts.allow 和 /etc/hosts.deny&#xff1f;匹配規則配置語法詳解配置示例允許特定 IP 訪問 SSH 服務拒絕整個子網訪問…

Spring AI:開啟Java開發的智能新時代

目錄 一、引言二、什么是 Spring AI2.1 Spring AI 的背景2.2 Spring AI 的目標 三、Spring AI 的核心組件3.1 數據處理3.2 模型訓練3.3 模型部署3.4 模型監控 四、Spring AI 的核心功能4.1 支持的模型提供商與類型4.2 便攜 API 與同步、流式 API 選項4.3 將 AI 模型輸出映射到 …

大白話面試中應對自我介紹

在面試中&#xff0c;自我介紹是開場的關鍵環節&#xff0c;它就像你遞給面試官的一張“個人名片”&#xff0c;要讓面試官快速了解你并對你產生興趣。下面詳細講講應對自我介紹的要點及回答范例。 一、自我介紹的時間把控 一般面試中的自我介紹控制在1 - 3分鐘比較合適。時間…

postman請求后端接受List集合對象

后端集合 post請求&#xff0c;即前端請求方式

Spark基礎篇 RDD、DataFrame與DataSet的關系、適用場景與演進趨勢

一、核心概念與演進背景 1.1 RDD(彈性分布式數據集) 定義:RDD 是 Spark 最早的核心抽象(1.0版本引入),代表不可變、分區的分布式對象集合,支持函數式編程和容錯機制。特點: 無結構化信息:僅存儲對象本身,無法自動感知數據內部結構(如字段名、類型)。編譯時類型安全…

軟件測試人員在工作中如何運用Linux?

軟件測試的小伙們就會明白會使用Linux是多么重要的一件事&#xff0c;工作時需要用到&#xff0c;面試時會被問到&#xff0c;簡歷中需要寫到。 對于軟件測試人員來說&#xff0c;不需要你多么熟練使用Linux所有命令&#xff0c;也不需要你對Linux系統完全了解&#xff0c;你只…

數據結構秘籍(二)圖(含圖的概念、存儲以及圖的兩大搜索)

1 引言 線性數據結構的元素滿足唯一的線性關系&#xff0c;每個元素&#xff08;初第一個和最后一個外&#xff09;只有一個直接前趨和一個直接后繼。樹形數據結構的元素之間有著明顯的層次關系。但是圖形結構的元素之間的關系是任意的。 什么是圖&#xff1f; 簡單來說&…

printf 與前置++、后置++、前置--、后置-- 的關系

# 前置和前置-- 先看一段代碼 大家是不是認為printf輸出的是 2 3 3 2 1 1 但是實際輸出的是 3 3 3 1 1 1 在這兩行printf函數代碼里&#xff0c;編譯器會先計算 a 和 --a 的值&#xff0c;然后再 從右向左 開始輸出。 printf函數中&#xff0c;如果有多個…

永磁同步電機無速度算法--反電動勢觀測器

一、原理介紹 在眾多無位置傳感器控制方法中&#xff0c;低通濾波反電勢觀測器結構簡單&#xff0c;參數整定容易&#xff0c;易于編程實現。但是該方法估計出的反電勢會產生相位滯后&#xff0c;需要在估計永磁同步電機轉子位置時進行了相位補償。 二、仿真模型 在MATLAB/si…

VS2015 c++和cmake配置編程

Visual Studio 2015&#xff1a;確保安裝了C開發工具&#xff0c;并安裝“使用C的桌面開發”工作負載。CMake&#xff1a;可以從 CMake官網 下載并安裝&#xff0c;并將其添加到系統環境變量中。vs加載項目啟動Visual Studio。選擇“繼續但無代碼”。點擊“文件”。選擇 “打開…