@microsoft/fetch-event-source实现流式接口打字机效果

实现服务器发送事件(Server-Sent Events, SSE)通信:

原生 EventSource@microsoft/fetch-event-source
HTTP 方法仅支持 GET

支持 GETPOST等任意 HTTP 方法

请求控制无法主动取消请求(依赖浏览器原生行为)支持 AbortController主动终止连接
请求头/Body仅支持部分简单请求头(如 Authorization支持自定义请求头、请求体(如 POST数据)
错误处理有限的重连控制(默认自动重连)可自定义重连策略(如指数退避)
兼容性现代浏览器(IE 不支持)依赖 fetchAbortController(现代浏览器)

具体版本:https://www.npmjs.com/package/@microsoft/fetch-event-source

npm install @microsoft/fetch-event-source

import React, { useRef } from 'react'
//​fetchEventSource​:微软实现的 SSE 客户端库
import { fetchEventSource } from '@microsoft/fetch-event-source'

    const index=()=>{
     //创建一个可变的引用对象 controllerRef,用于存储 AbortController实例
     const controllerRef = useRef(null);
    .
    .
    .
    .
     const handleFlu=()=>{
        controllerRef.current = new AbortController();

        const eventSource = fetchEventSource(接口, {
            method: 'POST',
            headers:{
            'Content-Type': 'application/json',
            }
            body: JSON.stringify({
                a:'搜索数据'
            }),
            signal: controllerRef.current.signal,
            openWhenHidden: true,
            onopen: (e) => {
                // 建立连接的回调
            },
           onmessage: (e) => {
              //此处应添加数据处理逻辑(如更新状态、渲染 UI 等)
                const res = JSON.parse(e.data)
                const {data}=res//此处解构出来的md数据可以通过md插件进行渲染

           }
           onclose: () => {
                controllerRef.current.abort();//// 主动终止请求
                eventSource.close();//// 关闭连接
            },
            onerror: () => {
                controllerRef.current.abort();// 错误时终止请求
                eventSource.close();
            },
}

}

在 Spring AI 中实现打字机效果,通常需要结合后端的流式输出和前端的动态渲染。这种效果的核心在于通过流式传输逐步将数据发送到前端,并在前端逐步展示,从而模拟出类似打字机的视觉体验。以下是实现效果的关键步骤和示例代码。 ### 后端实现(Spring AI + SSE) Spring AI 支持流式输出,可以通过 `SseEmitter` 或 `Flux` 等响应式编程方式将数据逐步发送到前端。以下是一个基于 `SseEmitter` 的示例: ```java import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; @RestController public class ChatController { @GetMapping("/stream") public SseEmitter streamResponse(@RequestParam String input) { SseEmitter emitter = new SseEmitter(60_000L); // 设置超时时间为60秒 // 模拟生成回复内容并逐步发送 new Thread(() -> { try { for (char c : generateResponse(input).toCharArray()) { emitter.send(c); Thread.sleep(100); // 控制发送速度,模拟打字机效果 } emitter.complete(); } catch (Exception e) { emitter.completeWithError(e); } }).start(); return emitter; } private String generateResponse(String input) { // 这里可以替换为调用 AI 模型的实际逻辑 return "This is a response to: " + input; } } ``` ### 前端实现(Vue 3 + JavaScript) 在前端,可以使用 `EventSource` 或 `fetch` 来接收 SSE 流,并逐步更新 DOM 元素的内容。以下是一个基于 Vue 3 的示例: ```vue <template> <div> <button @click="startStream">Start Streaming</button> <p>{{ streamedText }}</p> </div> </template> <script setup> import { ref } from 'vue'; const streamedText = ref(''); function startStream() { const eventSource = new EventSource('http://localhost:8080/stream?input=Hello'); eventSource.onmessage = function(event) { streamedText.value += event.data; }; eventSource.onerror = function(err) { console.error('EventSource failed:', err); eventSource.close(); }; } </script> ``` ### 响应式开发(Spring WebFlux) 如果使用 Spring WebFlux,可以通过 `Flux` 实现流式输出。以下是一个基于 `Flux` 的示例: ```java import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import reactor.core.publisher.Flux; import java.time.Duration; @RestController public class StreamController { @GetMapping("/flux-stream") public Flux<Character> fluxStream(@RequestParam String input) { return Flux.fromStream(generateResponse(input).chars().mapToObj(c -> (char) c)) .delayElements(Duration.ofMillis(100)); // 控制输出速度 } private String generateResponse(String input) { return "This is a response to: " + input; } } ``` 前端可以通过 `fetch` 和 `ReadableStream` 来处理响应流并逐步渲染: ```javascript async function startFluxStream() { const response = await fetch('http://localhost:8080/flux-stream?input=Hello'); const reader = response.body.getReader(); const decoder = new TextDecoder(); let text = ''; while (true) { const { done, value } = await reader.read(); if (done) break; text += decoder.decode(value, { stream: true }); document.getElementById('output').innerText = text; } } ``` ### 关键点 - **流式传输**:使用 `SseEmitter` 或 `Flux` 实现后端流式输出,逐步发送数据到前端- **前端渲染**:通过 `EventSource` 或 `fetch` 接收流数据,并动态更新 DOM。 - **控制速度**:通过 `Thread.sleep()` 或 `delayElements()` 控制数据发送的速度,以模拟打字机效果。 这些方法可以有效地在 Spring AI 应用中实现打字机效果,提升用户体验。[^1] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值