当前位置: 代码网 > it编程>编程语言>Javascript > vue3中使用sse最佳实践,封装工具详解

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

2024年09月08日 Javascript 我要评论
vue3使用sse最佳实践,封装工具工具// 接受参数export interface ssechatparams { url: string,// sse 连接 onmessage: (

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 事件。

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

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com