代码拉取完成,页面将自动刷新
后端使用SSE进行会话,前端使用Html模拟大模型的问答交互->【前端】+【后端】
SSE(Server-Sent Events)协议是一种用于在 Web 浏览器和服务器之间实现服务器向客户端单向实时通信的技术。下面将从多个方面详细介绍 SSE 协议:
SSE 允许服务器在建立连接后,持续向客户端发送更新信息。与传统的请求 - 响应模式不同,在 SSE 中,客户端发起一次请求,服务器保持该连接打开,并在有新数据时主动向客户端推送。
EventSource
对象来向服务器发起 HTTP 请求,请求的响应头中包含 Content-Type: text/event-stream
,表明这是一个 SSE 连接。\n\n
分隔。EventSource
对象会监听服务器发送的消息,并在接收到消息时触发相应的事件。SSE 消息由多个字段组成,每个字段以键值对的形式表示,字段之间用换行符分隔。常见的字段有:
data
:表示消息的实际内容。如果消息内容较长,可以分成多行,每行以 data:
开头。event
:可选字段,用于指定事件类型。如果指定了事件类型,客户端可以针对不同的事件类型进行不同的处理。id
:可选字段,用于为消息指定一个唯一的标识符。客户端可以使用这个标识符来实现消息的断点续传。retry
:可选字段,用于指定客户端在连接中断后重试连接的时间间隔(以毫秒为单位)。EventSource
对象,服务器端只需要按照特定的格式发送数据即可。id
字段实现消息的断点续传。EventSource
对象,无需额外的库或插件。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;
}
}
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);
}
}
}
<!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 = '';
// 创建一个新的EventSource
eventSource = 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>
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}`);
});
<!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>
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。