跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

使用 Axios 处理 Server-Sent Events (SSE) 数据流

本文旨在指导开发者如何在 前端 使用 Axios 处理 Server-Sent Events (SSE) 数据流,特别是在需要使用 POST 方法发送数据的情况下。文章将介绍一种基于 fetch-event-source 框架的解决方案,并提供其他可选方案,包括纯 JavaScript + Axios 的实现方式以及后端 Java (Spring) 的实现示例,以帮助读者全面理解和应用 SSE 技术。 前端处理 SSE 数据流 Server-Sent Events (SSE) 是一种允许服务器单向推送数据到客户端的技术,非常适合实时更新的应用场景。虽然 EventSource API 是处理 SSE 的标准方法,但它不支持 POST 请求。因此,当需要使用 POST 方法与 SSE API 交互时,我们需要寻找替代方案。 方案一:使用 fetch-event-source 框架 fetch-event-source 是一个强大的 JavaScript 库,它基于 fetch API,提供了对 SSE 的支持,并且可以灵活地处理各种 HTTP 方法,包括 POST。 安装: 虽然原文没有给出安装方式,但通常可以通过 npm 或 yarn 安装:
npm install fetch-event-source # 或者 yarn add fetch-event-source
使用示例:
import { fetchEventSource } from '@microsoft/fetch-event-source'; const data = { model: "gpt-3.5-turbo", prompt: "Say this is a test", max_tokens: 7, stream: true, temperature: 0 }; fetchEventSource('/my-service/chat', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'text/event-stream', // 明确指定 Accept 类型 'SESSION_ID': 'Header-Value' }, body: JSON.stringify(data), onmessage(event) { console.log("Received event:", event.data); // 处理接收到的数据 }, onerror(err) { console.error("Error:", err); }, onclose() { console.log("Connection closed"); } });
注意事项: 确保后端正确设置了 Content-Type 为 text/event-stream。 fetchEventSource 提供了一系列 回调函数 ,例如 onmessage、onerror 和 onclose,用于处理不同的事件。 body 必须是序列化后的 JSON 字符串。 方案二:纯 JavaScript + Axios 实现 另一种方法是结合使用 Axios 和 onDownloadProgress 回调函数,手动处理数据流。这种方法相对复杂,但可以避免引入额外的依赖。 Eclipse导入Android或其他的JAVA项目的正确方法 WORD版 本文档主要讲述的是Eclipse导入Android或其他的JAVA项目的正确方法;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看 下载
axios({ url: '/my-service/chat', // 替换为你的API端点 data: { prompt: 'json data' }, headers: { 'accept': 'text/event-stream', // 明确指定 Accept 类型 'content-type': 'application/json' }, method: 'POST', responseType: 'stream', // 重要: 指定 responseType 为 'stream' onDownloadProgress: progressEvent => { const xhr = progressEvent.event.target; const { responseText } = xhr; console.log("=====responseText======"); console.log(responseText); // 在这里处理接收到的数据流,例如解析 SSE 格式的数据 } }).then(({ data }) => Promise.resolve(data));
注意事项: responseType 必须设置为 stream,否则 Axios 不会触发 onDownloadProgress 回调。 onDownloadProgress 回调函数会多次触发,每次触发时 responseText 包含的是当前已接收到的所有数据。因此,你需要自行解析 SSE 格式的数据,并处理不完整的数据块。 这种方法对数据格式的依赖性较强,需要确保后端返回的数据符合 SSE 规范。 后端 Java (Spring) 实现示例 以下是使用 Spring Boot 创建 SSE 端点的示例代码:
import org.springframework.http.MediaType; import org.springframework.http.codec.ServerSentEvent; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import reactor.core.publisher.Flux; import java.time.Duration; import java.time.LocalTime; @RestController public class SSEController { @GetMapping(value = "/stream-sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux> streamSse() { return Flux.interval(Duration.ofSeconds(1)) .map(sequence -> ServerSentEvent.builder() .id(String.valueOf(sequence)) .event("periodic-event") .data("Server time: " + LocalTime.now()) .build()); } }
解释: @GetMapping(value = "/stream-sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE) 定义了一个处理 /stream-sse 请求的端点,并指定 produces 为 MediaType.TEXT_EVENT_STREAM_VALUE,表示返回 SSE 数据流。 Flux.interval(Duration.ofSeconds(1)) 创建一个每秒发送一次数据的流。 ServerSentEvent.builder() 用于构建 SSE 事件,可以设置 id、event 和 data 等属性。 客户端测试: 可以使用 WebClient 测试该端点:
import org.springframework.http.codec.ServerSentEvent; import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Flux; import java.time.LocalTime; public class SSEClient { public static void main(String[] args) { WebClient client = WebClient.create("http://localhost:8080"); Flux> eventStream = client.get() .uri("/stream-sse") .retrieve() .bodyToFlux(ServerSentEvent.class); eventStream.subscribe( content -> System.out.println("Time: " + LocalTime.now() + " - event: name[" + content.event() + "], id [" + content.id() + "], content[" + content.data() + "] "), error -> System.err.println("Error receiving SSE: " + error), () -> System.out.println("Completed!!!")); // Keep the application running for a while to receive events try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } } }
总结 本文介绍了在前端使用 Axios 处理 SSE 数据流的两种主要方法:使用 fetch-event-source 框架和使用纯 JavaScript + Axios。fetch-event-source 提供了更简洁易用的 API,而纯 JavaScript + Axios 则更加灵活,但需要手动处理数据流的解析。同时,文章也提供了后端 Java (Spring) 实现 SSE 端点的示例,帮助开发者构建完整的 SSE 应用。选择哪种方法取决于具体的应用场景和需求。在选择时,请考虑以下因素: 依赖性: 是否希望引入额外的依赖。 灵活性: 是否需要对数据流进行精细的控制。 复杂性: 代码的复杂程度和维护成本。 希望本文能够帮助你更好地理解和应用 SSE 技术。

相关文章