一、EventSource
1.如果接口地址是http协议的,使用EventSource。如果是ws的,使用webSocket
2.主动关闭流式请求连接的方式:source.close()
3.参考链接:Websocket 详解-CSDN博客
if (!!window.EventSource) {
// 建立连接
let source = new EventSource(window.config.baseURL + '/tsyp/stream?uuid=' + uuid);
//连接一旦建立,就会触发open事件
source.onopen = function (event) {
}
//客户端收到服务器发来的数据
source.onmessage = function (event) {
let data = event.data
if (data == "AIQA_EOF") {
source.close() //关闭请求的连接
}
}
//如果发生通信错误(比如连接中断),就会触发error事件
source.onerror = function (event) {
console.error('EventSource failed:', event);
}
} else {
console.warn("你的浏览器不支持SSE");
}
二、流式接口要求携带请求头
1.可以使用封装的EventSourcePolyfill。(此方法只能用get请求)
但注意:EventSourcePolyfill发送的请求可以携带请求头,但是只能是get请求
async putQuestion(query) {
let that = this
// 建立连接
let source = new EventSourcePolyfill(`/eventSourceFill/chat/conversation/stream`,
{
withCredentials: true,
headers: {
"Content-Type": "application/json",
Authorization: 'Bearer ' + getToken(),
connection: "keep-alive",
}
});
//连接一旦建立,就会触发open事件
source.onopen = function (event) {
source.send('Authorization: Bearer ' + getToken());
console.log("连接建立成功")
}
//客户端收到服务器发来的数据
source.onmessage = function (event) {
let data = event.data
console.log("data:", data)
if (data == "AIQA_EOF") {
source.close()
} else {
}
}
//如果发生通信错误(比如连接中断),就会触发error事件
source.onerror = function (event) {
console.error('EventSource failed:', event);
}
},
2.请求要求携带请求头(post、get请求均可)
async sendRequest(query) {
let controller = new AbortController();
let {signal} = controller;
//controller.abort() 用于取消fetch接口请求
this.cancel_QA = controller
//使用fetch发送请求
const response = await fetch('http://****/chat/conversation/stream', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + getToken()
},
body: JSON.stringify(query),
signal
});
// 检查响应是否成功
if (!response.ok) {
console.error('网络响应失败:', response.statusText);
return;
}
// 获取响应体的可读流
const reader = response.body.getReader();
const decoder = new TextDecoder('utf-8');
// 逐块读取数据
while (true) {
const {done, value} = await reader.read();
if (done) break; // 流结束
let msg = decoder.decode(value, {stream: true})
if (msg.includes("LLM-EOF")) {
console.warn("回答结束")
this.cancel_QA = null
} else {
}
}
},