当前位置: 首页 > news >正文

vue3 中使用 sse 最佳实践,封装工具

在这里插入图片描述

工具

// 接受参数
export interface SSEChatParams {url: string,// sse 连接onmessage: (event: MessageEvent) => void,// 处理消息的函数onopen: () => void,// 建立连接触发的事件finallyHandler: () => void,// 相当于 try_finally 中的 finally 部分,不管出现异常或者关闭必然会执行的代码块
}class SSEService {private eventSource: EventSource | null = null;private finallyHandler: (() => void) | undefined;// 建立连接connect(sseChatParams: SSEChatParams) {this.finallyHandler = sseChatParams.finallyHandler;this.eventSource = new EventSource(sseChatParams.url);if (sseChatParams.onopen != null) {this.eventSource.onopen = sseChatParams.onopen;}else{this.eventSource.onopen = () => {console.log('SSE 连接已开启');};}if (sseChatParams.onmessage != null) {this.eventSource.onmessage = sseChatParams.onmessage;} else {this.eventSource.onmessage = (event) => {console.log('收到消息:', event.data);};}this.eventSource.onerror = (error) => {if (this.eventSource?.readyState === EventSource.CLOSED) {console.log("SSE 连接已关闭");} else {console.error("SSE 错误:", error);}sseChatParams.finallyHandler();};}// 关闭连接disconnect() {if (this.eventSource) {this.eventSource.close();console.log("关闭 sse 连接")if (this.finallyHandler != null) {this.finallyHandler();}}}
}export const sseService = new SSEService();

使用

我在我代码中是这样使用的,就这么简单

const onopen = () => {console.log("建立无敌 sse 连接成功")
}
// 建立连接
let sseChatParams: SSEChatParams = {onopen,url: import.meta.env.VITE_GLOB_API_URL + 'sse/createConnect?clientId=' + userStore.getSseClientId(),onmessage: (event: MessageEvent) => {// 收到消息console.log('收到消息xsssx:', event.data);let chunk = event.data;if (chunk === '[DONE]') {sseService.disconnect()state.imageList = []chatGuide(chatStore.activeChatId).then(resp => {chatGuideList.value = resp.data.guideListscrollViewBottom()})return}chunk = JSON.parse(chunk)if (chunk.type === 'error') {errorText = chunk.contentconsole.log("errorText", errorText);updateChatData(errorText)return;}chunk = chunk.content;if (!chunk) {return;}lastText = lastText + chunk// 更新聊天数据源中的对话updateChatData(lastText)},finallyHandler: () => {console.log("finallyHandler操作")sessionStatus.value = 0inputDisabled.value = falsedataSources.value[dataSources.value.length - 1].loading = falseloading.value = falseif (!isMobile.value) {// 聚焦输入框inputRef.value?.focus()}}
};
sseService.connect(sseChatParams)

另外你可能还需要增加一下关闭触发时机

// 当组件从 DOM 中卸载前执行的操作
onUnmounted(() => {sseService.disconnect()
})

这里需要提一嘴,关于 sse 中的 onopen 触发时机

当你和服务器建立 sse 连接的时候,如果后端没有通过 sse 返回给你消息的话,那么前端浏览器大概率是不会触发 onopen 事件。

所以当与后端建立连接后要注意咯~


最后介绍一下自己的网站术士 AI:术士AI 2.0 (shushiai.com)

有兴趣用用玩玩,最好也支持一下,谢谢

http://www.lryc.cn/news/252904.html

相关文章:

  • OpenCV快速入门【完结】:总目录——初窥计算机视觉
  • 车企数据治理实践案例,实现数据生产、消费的闭环链路 | 数字化标杆
  • 深入学习锁--Lock各种使用方法
  • 计算机毕设:基于机器学习的生物医学语音检测识别 附完整代码数据可直接运行
  • VMware安装Ubuntu系统(Server端,Desktop端步骤一样)
  • Navicat 与 华为云 GaussDB 合作再升级,赋能 GaussDB 分布式数据库
  • 【Docker】从零开始:13.Docker安装tomcat
  • 风控规则引擎(一):Java 动态脚本
  • 第五十六天|583. 两个字符串的删除操作 72. 编辑距离
  • java中Lists.newArrayList和new ArrayList的详细区别?
  • 从图片或PDF文件识别表格提取内容的简单库img2table
  • CSV文件中使用insert 函数在指定列循环插入不同数据
  • 【华为OD题库-064】最小传输时延I-java
  • 全文检索[ES系列] - 第495篇
  • 【预计IEEE出版|EI征稿通知】第六届下一代数据驱动网络国际学术会议 (NGDN 2024)
  • C++软件在Win平台运行总结
  • 【数电笔记】16-卡诺图绘制(逻辑函数的卡诺图化简)
  • 前端面试灵魂提问(1)
  • Linux中项目部署步骤
  • cmd下查看python命令的用法
  • 大型语言模型在实体关系提取中的应用探索(二)
  • Easy Excel设置表格样式
  • HarmonyOS/OpenHarmony应用开发
  • 孩子都能学会的FPGA:第二十一课——用线性反馈移位寄存器实现伪随机序列
  • 国内 AI 成图第一案!你来你会怎么判?
  • 快速登录界面关于如何登录以及多账号列表解析以及config配置文件是如何读取(1)
  • finebi 新手入门案例
  • 1. 小游戏(贪心)
  • 记录 | c++打印变量类型
  • nodejs_vue+vscode美容理发店会员管理系统un1dm