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"

完

相关推荐
墨神谕9 小时前
RPC框架与HTTP REST的区别
网络协议·http·rpc
HY小宝F10 小时前
树莓派智能摄像头系统 30 天重学计划之 Day 04 · HTTP / API:控制链入口 —— 学习总结
网络协议·学习·http
蜗牛互联网11 小时前
Java标准HTTP调用多模态模型的票据抽取前置校验
java·人工智能·python·http
深蓝电商API1 天前
HTTP/2 协议逆向:从 Fiddler 抓不到包说起
爬虫·网络协议·http·fiddler
fthux1 天前
开源小工具 Who Arrives:看看你的公网 IP、地区、时区和网络
http·开源·github
程序员z72 天前
【从0开始学计算机网络】| HTTP 协议的进化史
网络协议·计算机网络·http
长按助力退休2 天前
HTTP缓存从强缓存到协商缓存,前端性能优化第一步
http
imDwAaY3 天前
WebSocket 和 SSE 有什么区别?从实时通信到 AI 流式输出
后端·websocket
Knight_AL3 天前
基于 Netty 实现的 WebSocket 服务端
网络·websocket·网络协议