一、背景
SSE 是指服务器发送事件(Server-Sent Events),它是一种用于在客户端和服务器之间单向实时通信的 Web 技术。通过 SSE,服务器可以向客户端发送异步事件流,而无需客户端发起请求。
原生的EventSource 不能使用post方法,只能使用get方法,而且还不能自定义请求header,所以这里使用npm包
二、npm包
event-source-polyfill:可以自定义请求头
fetch-event-source:可使用post请求,但没正式发布,使用的人不多
@microsoft/fetch-event-source:自定义请求头,且可使用post请求,不兼容IE浏览器
三、实现代码
import { EventSourceMessage, fetchEventSource } from "@microsoft/fetch-event-source"
export function usePrompt() {
const store = useLocalStore(()=>{
submitCustomPrompt: async ({ id, content, qasStore, isReload }) => {
try {
let text = "";
const url = `${protocol}${hostname}${port}/api/custom-prompt`
await fetchEventSource(url,
{
method: "POST",
headers: {
Authorization: `Bearer ${auth.oauth2Token?.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
id: id,
content: content,
}),
onmessage(event: EventSourceMessage) {
let data: customPromptPostRes = { results: "", results_id: "", status: "processing" };
try {
data = JSON.parse(event.data);
} catch {
console.error("onmessage error");
}
if (!data.results_id) return;
qasStore.updatePromptCard({
text: data.results,
idx: qasStore.contents.length - 1,
err: !data.results,
});
if (data?.status === "completed") {
text = data.results || intl.formatMessage({ id: "cognitive.prompt.empty" });
}
},
onerror(error) {
throw error;
},
async onopen(response) {
if (response?.status !== 200) {
throw response;
}
}
}
);
return text;
} catch (err) {
if (err?.status === 401) {
await getRefreshToken();
store.submitCustomPrompt({
id,
content,
qasStore,
isReload: true,
});
return "";
};
if(err?.status) {
message.warning(intl.formatMessage({ id: `err.${err?.status}` }));
} else {
message.warning(toastErrPointHandle(intl.formatMessage({ id: "err.500000000" })));
}
return "";
}
},
})
return store;
}
export default usePrompt;
ps:后端的报错(连接成功后的操作)需要通过onopen(response){}才能拿到;而连接错误的信息需要通过onerror(error){}拿到