118 http 协议中如何实现流式的交互数据

前言

我们经常 会碰到的 基于 http 流式交互的数据方式

一般在 现在常见的大模型中, 一般是基于 websocket 来进行流式交互

这里 来介绍一下 基于 http 的流式数据交互

基于 http 协议的流式数据交互 - 服务器

主要是基于 println 和 flush

复制代码
@RestController
@RequestMapping("/HelloWorld")
public class HelloWorldController {

    @PostMapping("/flowResponse")
    public void flowResponse(HttpServletResponse response) throws Exception {
        response.setContentType("text/event-stream");
        response.setCharacterEncoding("utf8");
        PrintWriter pw = response.getWriter();

        for (int i = 1; i < 10; i++) {
            pw.println(String.format("this is section %s", i));
            pw.flush();
            Thread.sleep(1000);
        }
    }

}

基于 http 协议的流式数据交互 - 客户端

发送请求这边的处理如下

复制代码
/**
 * Test26PostFlowRequest
 *
 * @author Jerry.X.He <970655147@qq.com>
 * @version 1.0
 * @date 2024-07-30 21:29
 */
public class Test26PostFlowRequest {

    // Test26PostFlowRequest
    public static void main(String[] args) {

        String url = "http://localhost:8080/HelloWorld/flowResponse";
        Map<String, String> headers = URLConnectionUtils.commonHeaders();
        String postBody = "{}";
        URLConnectionUtils.postBodyWithFlow(url, headers, postBody, "utf8", line -> {
            System.out.println(line);
        });

    }

}

postBodyWithFlow 的处理如下

发送 http 请求, 然后 一行一行的处理接收到的数据

复制代码
    /**
     * postBodyWithFlow
     *
     * @return java.lang.String
     * @author Jerry.X.He
     * @date 2024/7/30 20:26
     */
    public static HttpResponse postBodyWithFlow(String urlStr, Map<String, String> headers, String postBody,
                                            String respCharset, Consumer<String> func) {
        HttpURLConnection conn = null;
        try {
            disableSSLVerification();
            URL url = new URL(urlStr);
            conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");//POST GET PUT DELETE
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                conn.setRequestProperty(entry.getKey(), entry.getValue());
            }
            conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.connect();
            OutputStream os = conn.getOutputStream();
            os.write(postBody.getBytes());
            os.flush();
            os.close();

            HttpResponse result = new HttpResponse();
            result.setUrl(conn.getURL());
            result.setMethod(conn.getRequestMethod());
            result.setHeaders(conn.getHeaderFields());
            result.setResponseCode(conn.getResponseCode());
            result.setResponseMessage(conn.getResponseMessage());

            StringBuilder respFromServer = new StringBuilder();
            // if success, read response from server
            if (conn.getResponseCode() >= 200 && conn.getResponseCode() < 300) {
                if (respCharset == null) {
                    respCharset = getCharsetFromServer(result);
                }

                BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), respCharset));
                String line = null;
                while ((line = reader.readLine()) != null) {
                    func.accept(line);
                    respFromServer.append(line).append("\r\n");
                }
            }

            result.setRespCharset(respCharset);
            result.setRespFromServer(respFromServer.toString());
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }
    }

演示效果

一秒中输出一个 "this is section $id"

完

相关推荐
web打印社区14 小时前
Lodop排障总纲-常见报错一张表
开发语言·前端·javascript·chrome·websocket
嵌入式学习菌19 小时前
HTTP/HTTPS、MQTT/MQTTS 区别
网络协议·http·https
情 九1 天前
MCP 实战 06:把 HTTP 接口接成工具,让 AI 帮你查数据
人工智能·网络协议·http·mcp
Da Da 泓1 天前
五子棋 Web 端测试用例报告
前端·网络·websocket·网络协议·测试用例·项目
步行cgn2 天前
HTTP 请求报文结构详解:请求行、请求头、请求体各自的作用
网络·网络协议·http
明天也要努力学习2 天前
HTTP 协议的基本格式和 fiddler 的用法
网络协议·http·fiddler
cpolar技术支持2 天前
网关加 gzip,同时开启 chunked,下载回来的包解不开:把两层编码的解压顺序与长度核对做成只读页
python·http·网络编程·socket·内网穿透
web打印社区3 天前
Chrome-kiosk-printing能上生产吗
开发语言·前端·javascript·chrome·websocket
骑着蜗牛撵大象3273 天前
手写一个 HTTP 服务器:从 socket 到 epoll,Linux 上到底怎么把请求变成响应
linux·服务器·网络·http·epoll·socket编程·并发模型
沫璃染墨3 天前
从零入门计算机网络系列(十):HTTP协议进阶——从资源路径解析到状态码与请求头详解
linux·运维·服务器·网络·c++·http