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

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.guideList
        scrollViewBottom()
      })
      return
    }
    chunk = JSON.parse(chunk)
    if (chunk.type === 'error') {
      errorText = chunk.content
      console.log("errorText", errorText);
      updateChatData(errorText)
      return;
    }
    chunk = chunk.content;
    if (!chunk) {
      return;
    }
    lastText = lastText + chunk
    // 更新聊天数据源中的对话
    updateChatData(lastText)
  },
  finallyHandler: () => {
    console.log("finallyHandler操作")
    sessionStatus.value = 0
    inputDisabled.value = false
    dataSources.value[dataSources.value.length - 1].loading = false
    loading.value = false
    if (!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.kler.cn/news/157133.html

相关文章:

  • 堆排序详细解读
  • 记录 | pip加速配置
  • Java中的锁
  • 一文打尽相机单目标定(远心,沙姆镜头)
  • 2024搞钱方式,这些你都了解吗?
  • Java NIO SelectionKey
  • 使用求2个字符串最长公共子序列的方法来实现 git diff 算法 java 实现
  • Kotlin学习之集合
  • 使用JAVA语言写一个排队叫号的小程序
  • C++ 系列 第四篇 C++ 数据类型上篇—基本类型
  • 数据结构学习笔记——广义表
  • 实体、协议、服务和服务访问点
  • 【重点】【滑动窗口】239. 滑动窗口最大值
  • Appium:iOS部署
  • 深度学习在训练时更新和保存最佳训练结果的方法(字典方法,本地保存方法,模型深拷贝方法)
  • selenium中元素定位正确但是操作失败,6种解决办法全搞定
  • 六、ZooKeeper Java API操作
  • 【数据结构】——栈|队列(基本功能)
  • Python字符串模糊匹配工具:TheFuzz 库详解
  • 关于使用百度开发者平台处理语音朗读问题排查
  • Spring-Security取消验证-Get请求接口正常,Post请求报错403
  • java后端技术演变杂谈(未完结)
  • c语言笔记之小项目家庭收支记账软件
  • java synchronized详解
  • ruby安装(vscode、rubymine)
  • 「Qt Widget中文示例指南」如何创建一个计算器?(二)
  • 深度学习(五):pytorch迁移学习之resnet50
  • MySQL安装,建立,导入本地Txt文件
  • 寻找两个有序数组的中位数算法(leetcode第4题)
  • Android 7.1 点击清空全部按钮清空一切运行进程(包括后台在播音乐)