香
大模型分析完成返回消息是EventStream
1.通过fetch来进行流的读取
fetch("http://xxx/chat/kb_chat", {
method: "post",
headers: {
"Content-Type": "application/json", // 如果发送JSON数据
},
body: JSON.stringify({
query: "xxx",
mode: "local_kb",
kb_name: "demo",
top_k: 3,
score_threshold: 2,
history: [],
stream: true,
model: "glm4-chat",
temperature: 0.7,
max_tokens: 0,
prompt_name: "default",
return_direct: false,
}),
})
.then((response) => {
if (!response.ok) {
throw new Error("Network response was not ok");
}
// 使用response.body.getReader()来读取流
const reader = response.body.getReader();
function read() {
reader
.read()
.then(({ value, done }) => {
// value是一个Uint8Array,需要转换为字符串
if (value) {
const textDecoder = new TextDecoder("utf-8");
const data = textDecoder.decode(value);
console.log(data); // 处理数据
if (!done) {
read(); // 继续读取
}
}
})
.catch(console.error);
}
read(); // 开始读取
})
.catch(console.error);
2.@microsoft/fetch-event-source
npm install @microsoft/fetch-event-source@2.0.1
import { fetchEventSource } from "@microsoft/fetch-event-source";
async fun() {
await fetchEventSource(`${process.env.VUE_APP_LANG_API}/chat/kb_chat`, {
method: "post",
headers: {
"Content-Type": "application/json", // 如果发送JSON数据
},
body: JSON.stringify({
query: "xxxx",
mode: "local_kb",
kb_name: "xx",
top_k: 3,
score_threshold: 2,
history: [],
stream: true,
model: "glm4-chat",
temperature: 0.7,
max_tokens: 0,
prompt_name: "default",
return_direct: false,
}),
onmessage(ev) {
// console.log(ev.data);
let xx = JSON.parse(ev.data);
console.log(xx);
},
});
},
添加更好的错误处理
class RetriableError extends Error { }
class FatalError extends Error { }
fetchEventSource('/api/sse', {
async onopen(response) {
if (response.ok && response.headers.get('content-type') === EventStreamContentType) {
return; // everything's good
} else if (response.status >= 400 && response.status < 500 && response.status !== 429) {
// client-side errors are usually non-retriable:
throw new FatalError();
} else {
throw new RetriableError();
}
},
onmessage(msg) {
// if the server emits an error message, throw an exception
// so it gets handled by the onerror callback below:
if (msg.event === 'FatalError') {
throw new FatalError(msg.data);
}
},
onclose() {
// if the server closes the connection unexpectedly, retry:
throw new RetriableError();
},
onerror(err) {
if (err instanceof FatalError) {
throw err; // rethrow to stop the operation
} else {
// do nothing to automatically retry. You can also
// return a specific retry interval here.
}
}
});
在我测试的时候发现 切换浏览器标签页 会重新发送一次链接 还有出现下图这种也会重新发送新的链接
最终解决办法 参考
xxx() {
this.fenxiLoad = true; // 标记是否结束
let that = this;
class RetriableError extends Error {}
class FatalError extends Error {}
this.content = "";
// 文件对话
fetchEventSource(`${process.env.VUE_APP_LANG_API}/chat/kb_chat`, {
method: "post",
openWhenHidden: true,
headers: {
"Content-Type": "application/json", // 如果发送JSON数据
},
body: JSON.stringify({
query: "xxx",
mode: "local_kb",
kb_name: "666",
top_k: 3,
score_threshold: 2,
history: [],
stream: true,
model: "glm4-chat",
temperature: 0.7,
max_tokens: 0,
prompt_name: "default",
return_direct: false,
}),
onmessage(ev) {
let xx = JSON.parse(ev.data);
console.log(xx);
let choices = (xx.choices && xx.choices[0].delta.content) || "";
that.content += choices;
},
onclose() {
that.fenxiLoad = false;
// if the server closes the connection unexpectedly, retry:
throw new RetriableError();
},
onerror(err) {
that.fenxiLoad = false;
if (err instanceof FatalError) {
throw err; // rethrow to stop the operation
} else {
// do nothing to automatically retry. You can also
// return a specific retry interval here.
// alert("请重试");
// that.peopleFenxi();
console.log(err.message);
if (err.message) {
that.$message.error("分析失败了,请点击重新分析");
} else {
that.$message.success("分析完成!");
}
return 100000000000000;
}
},
});
},