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

【Java】SpringBoot模拟流式输出,前端使用流式接收数据并打印

现在AI的接口由于生成内容比较慢都是采用的流式输出的方式。这里将模拟一下流式输出。

后端接口

import cn.hutool.json.JSONUtil;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/test")
public class TestController {

    @PostMapping("/stream")
    public ResponseEntity<StreamingResponseBody> streamData() {
        Map<String, String> map = new HashMap<>();
        map.put("content", "内容");

        StreamingResponseBody responseBody = outputStream -> {
            try (PrintWriter writer = new PrintWriter(outputStream)) {
                for (int i = 0; i < 10; i++) {
                    map.put("content", "内容:" + i);
                    writer.println(JSONUtil.toJsonStr(map));
                    writer.flush();
                    // 模拟一些延迟
                    Thread.sleep(500);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.TEXT_PLAIN);
        // 指示这是一个流式响应
        headers.setContentLength(-1L);

        return new ResponseEntity<>(responseBody, headers, HttpStatus.OK);
    }
}

传统非流式-前端

url = 'http://127.0.0.1:8080/test/stream'
async function getResp(){
	const startTime = performance.now();
	console.log("非流式输出")
	const resp = await fetch(url,{
		method: 'POST',
		headers: {
			'Content-Type': 'application/json'
		},
		body: JSON.stringify({
			content: '讲个笑话'
		})
	});
	const msg = await resp.text();
	console.log(msg)
	const endTime = performance.now();
	console.log(`执行耗时: ${endTime - startTime} ms`);
}
getResp()

测试结果如下,程序会等待所有内容都返回了,才输出内容
在这里插入图片描述

流式-前端

async function getRespStream(){
	console.log("流式输出")
	const resp = await fetch(url,{
		method: 'POST',
		headers: {
			'Content-Type': 'application/json'
		},
		body: JSON.stringify({
			content: '讲个笑话'
		})
	});
	
  const reader = resp.body.getReader();
	while(1){
		// value 是类型化数组
		const textDecoder = new TextDecoder()
		const {done,value} = await reader.read();
		if(done){
			break
		}
		const str = textDecoder.decode(value)
		console.log(str)
	}
}
getRespStream()

可以看到后端只要输出一段内容前端就会打印一段内容。
在这里插入图片描述


http://www.kler.cn/a/400030.html

相关文章:

  • 一文说清:c++标准库
  • Macmini中普通鼠标与TrackPad联动问题解决
  • 智能网页内容截图工具:AI助力内容提取与可视化
  • 【HarmonyOS】鸿蒙系统在租房项目中的项目实战(二)
  • 深度学习神经网络创新点方向
  • gitlab和jenkins连接
  • 【数据结构与算法】排序
  • electron客户端预览doc、docx、excel、pdf、ppt、csv、txt等文件类型
  • ASUS/华硕灵耀X双屏Pro UX8402Z 原厂Win11-22H2系统 工厂文件 带ASUS Recovery恢复
  • 【大语言模型】ACL2024论文-16 基于地图制图的罗马尼亚自然语言推理语料库的新型课程学习方法
  • CSS复合选择器详解与应用指南
  • ArcMap 操作矢量要素的旋转、复制等功能
  • 网关在能源物联网中扮演了什么角色?
  • django从入门到实战(四)——模型与数据库
  • 基于微信小程序的河池旅游设计与实现
  • 微服务day11-微服务面试
  • 6.k8s:devops
  • 【Linux】Linux入门实操——定时任务调度
  • 坚果云·无法连接服务器(无法同步)
  • 16.100ASK_T113-PRO 配置QT运行环境(二)
  • 【GeekBand】C++设计模式笔记12_Singleton_单件模式
  • ESP-IDF VScode 项目构建/增加组件 新手友好!!!
  • css uniapp背景图宽度固定高度自适应可以重复
  • Python 人脸检测:使用 Dlib 和 OpenCV
  • OSRM docker环境启动
  • blockchain实现遇到的问题