前端js+vue承接后端SSE流式输出结果

前置

解释:
Server-Sent Events:服务器发送事件,是一种基于 HTTP 的轻量级协议,允许服务器主动向客户端推送文本数据(如 JSON、纯文本等)
特点:

  • 单向通信:仅服务器 → 客户端方向
  • 基于 HTTP/HTTPS:无需特殊协议
  • 自动重连:浏览器内置支持断线重连
  • 简单易用:前端直接使用 EventSource API

注意:

  • 前端 SSE 格式解析:会自动忽略 data: 前缀和 \n\n 分隔符
  • 服务器返回 5xx 错误会触发 error 事件
  • 网络中断会自动重连(默认 3 秒重试)

流程:

前端 (Vue)       → 发起SSE请求 →   Spring Boot (Controller)
  ↓                                   ↓
(EventSource)    ← 流式数据 ←   WebClient → 大模型API (流式HTTP)

前端 js 代码

<template>
  <div>
    <button @click="startStream">开始接收流</button>
    <button @click="closeStream">停止</button>
    <div>{{ streamData }}</div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      streamData: "",
      eventSource: null
    };
  },
  methods: {
    startStream() {
      // 1. 创建EventSource连接
      this.eventSource = new EventSource("http://your-spring-api/sse-stream");

      // 2. 监听消息事件
      this.eventSource.addEventListener("message", (event) => {
        // 实际数据在 event.data 中
        this.streamData += event.data; // 追加到页面
      });

      // 3. 监听错误事件
      this.eventSource.addEventListener("error", (err) => {
        console.error("SSE error:", err);
        this.closeStream(); // 出错时关闭连接
      });
    },
    closeStream() {
      if (this.eventSource) {
        this.eventSource.close(); // 主动关闭连接
        this.eventSource = null;
      }
    }
  },
  beforeDestroy() {
    this.closeStream(); // 组件销毁时清理
  }
};
</script>

扩展

自定义事件类型:

后端发送:event: update\ndata: {…}\n\n

前端监听:.addEventListener(“update”, handler)

为了在 Vue 3 中使用 `setup` 语法并结合流式响应实现类似“吐字”效果的功能,可以通过 `EventSource`(Server-Sent Events,SSE)从后端获取流式数据,并逐字追加显示在前端界面上。这种方式适用于服务器持续发送数据、客户端只需单向接收的场景。 ### 实现思路 - 使用 `EventSource` 建立与后端SSE 连接。 - 接收数据时,将字符串逐字追加到页面上。 - 利用 `ref` 和响应式数据更新视图。 - 可以通过 `setTimeout` 控制逐字显示的速度,模拟“打字”效果。 ### 示例代码 以下是一个基于 Vue 3 `setup` 的实现示例: ```vue <template> <div class="container"> <h1>SSE 流式输出 - 吐字效果</h1> <div id="output">{{ currentText }}</div> </div> </template> <script setup lang="ts"> import { ref, onMounted } from 'vue'; const currentText = ref<string>(''); const fullText = ref<string>(''); const typingSpeed = 50; // 打字速度,单位为毫秒 const startTyping = () => { let index = 0; const interval = setInterval(() => { if (index < fullText.value.length) { currentText.value += fullText.value.charAt(index); index++; } else { clearInterval(interval); } }, typingSpeed); }; onMounted(() => { const eventSource = new EventSource('http://localhost:5000/stream'); eventSource.onmessage = (event) => { fullText.value = event.data; // 接收完整文本 startTyping(); // 开始逐字显示 }; eventSource.onerror = (err) => { console.error('EventSource failed:', err); }; }); </script> <style scoped> #output { white-space: pre-wrap; font-size: 1.2em; margin-top: 20px; border: 1px solid #ddd; padding: 10px; } </style> ``` ### 说明 - **`fullText`** 存储从后端接收的完整文本内容。 - **`currentText`** 用于绑定到模板,实现逐字显示。 - **`startTyping`** 函数控制逐字添加的效果,通过 `setInterval` 模拟打字节奏。 - 使用 `EventSource` 连接到后端 `/stream` 接口,接收流式数据[^2]。 ### 注意事项 - 确保后端支持 SSE 并正确设置响应头,如 `Content-Type: text/event-stream`。 - 若需要支持双向通信或更复杂的交互,可考虑使用 WebSocket。 - 在生产环境中,建议添加错误处理和连接重试机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

abcnull

您的打赏是我创作的动力之一

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值