背景:

使用okhttp框架进行网络访问时,一般会使用 HttpLoggingInterceptor 打印请求和响应的log。在使用okhttp访问AI大模型时,如果选择流式输出,那么响应的body数据使用的SSE技术,服务异步发送大模型生成的增量token,使用HttpLoggingInterceptor拦截后,会在所有数据接收完成后一次打印完,业务逻辑处也是在log打印完后,才集中收到全部的内容,达不到流式返回的效果。

优化方案:

优化的思路是将body 流拦截打印,然后重新构建response,responsebody和inputstream。将真实的body数据重新写入到重新构建的responsebody流里面,这样业务端就会实时收到流式返回的内容。下面是拦截打印body部分的代码:

@Override
public Response intercept(@NotNull Chain chain) throws IOException {Response response = chain.proceed(chain.request());PipedOutputStream pipedOutputStream = new PipedOutputStream();PipedInputStream pipedInputStream = new PipedInputStream(pipedOutputStream);BufferedSource cloneSource = Okio.buffer(Okio.source(pipedInputStream));ResponseBody cloneBody = ResponseBody.create(cloneSource, response.body().contentType() , response.body().contentLength());Response cloneResponse = response.newBuilder().body(cloneBody).build();BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(pipedOutputStream));InputStream inputStream = response.body().byteStream();BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));new Thread(() -> {String line;while (true) {try {if ((line = reader.readLine()) == null) break;} catch (IOException e) {e.printStackTrace();break;}System.out.println(">>>>>>>>>>>>> log intercept:" + line);try {writer.write(line);writer.write("\r\n");writer.flush();} catch (IOException e) {e.printStackTrace();}}try {writer.close();} catch (IOException e) {e.printStackTrace();}System.out.println("log intercept end");}).start();return cloneResponse;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/86539.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/86539.shtml
英文地址,请注明出处:http://en.pswp.cn/web/86539.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

看数据世界的历史:全面梳理从关系库、大数据到AI时代的数据发展及展望

序章 在数据库不断发展的时代里,我们看到了关系型数据库(RDB)在一次次的数据演变过程中的占据王位,捍卫了胜利,像一个王朝更替下的“王权”的故事,精彩有趣。 本篇就来探讨下数据库的发展兴衰史&#xff0…

元宇宙与人工智能的融合:从虚拟世界到智能生态的IT新革命

文章目录 引言:前沿技术重塑数字交互体验一、元宇宙与AI融合的本质:虚拟空间与智能交互的交汇元宇宙赋能AI:AI赋能元宇宙: 二、元宇宙与AI融合的演进:从概念到产业热潮三、核心技术:元宇宙与AI融合的基石与…

问卷调查[mqtt dht]

任务 this code uses esp32-wroom-32 and dht11 to read the humidty and temperature, besieds, it will send the meassage to the cloud platform. All communication is conducted through MQTT. 打分标准 您应该对以下代码进行评级,并且必须遵守如…

swift 对象转Json

在 Swift 中将对象转换为 JSON 可以通过以下方法实现: 使用 Codable 协议 Swift 的 Codable 协议(Encodable 和 Decodable 的组合)是处理 JSON 编码和解码的推荐方式。 struct Person: Codable {var name: Stringvar age: Int }let person…

Python学习Day43

学习来源:浙大疏锦行 import torch import torch.nn as nn import torch.nn.functional as F import torchvision import torchvision.transforms as transforms import numpy as np import matplotlib.pyplot as plt from PIL import Image import os # 设置随机…

了解一下Unity AssetBundle 的几种加载方式

Unity 的 AssetBundle 系统提供了多种加载方式,以满足不同场景下的资源管理和性能需求。 同步加载(LoadFromFile) 同步加载使用 AssetBundle.LoadFromFile 方法从文件系统中直接加载 AssetBundle。这种方式会阻塞主线程,直到加载…

鸿蒙边缘智能计算架构实战:多线程图像采集与高可靠缓冲设计

目录 一、技术背景与挑战二、鸿蒙边缘计算架构的核心特性1. 分布式软总线:打破设备孤岛2. 轻量化多线程模型 三、多线程图像采集的稳定性设计1. 分层缓冲队列架构2. 线程优先级策略 四、边缘侧高可靠缓冲机制1. 基于分布式数据管理的容错设计2. 动态带宽调节 五、实…

excel中vba开发工具

1、支持单元格点击出现弹框进行选择 支持模多次模糊查询 Private Sub CommandButton1_Click() Call vehicle_查询 End SubPrivate Sub Worksheet_Activate()Call vehicle_取出车架号和公司名称 取出不重复的车架号Sheet13.ComboBox1.Visible False 车架号显示Sheet13.ComboB…

CatBoost:征服类别型特征的梯度提升王者

基于有序提升与对称树的下一代GBDT框架,重塑高维分类数据处理范式 一、CatBoost的诞生:解决类别特征的终极挑战 2017年由俄罗斯Yandex团队开源,CatBoost(Categorical Boosting)直指机器学习中的核心痛点:类…

使用 WSL 启动ubuntu.tar文件

使用 WSL 启动ubuntu.tar文件,可按以下步骤进行3: 检查 WSL 版本:确保你的 WSL 版本为 2.4.8 或更高版本。可以在命令行中输入wsl --update来更新 WSL 到最新版本。 设置默认 WSL 版本:如果还没有将 WSL 2 设置为默认版本&#x…

vue-23(创建用于逻辑提取的可重用组合组件)

创建用于逻辑提取的可重用组合组件 可重用的组合式是 Vue 组合式 API 的基石,它使你能够在多个组件中提取和重用有状态逻辑。这有助于编写更清晰的代码,减少冗余,并提高可维护性。通过将特定功能封装到组合式中,你可以轻松地共享…

数据透视表学习笔记

学习视频:Excel数据透视表大全,3小时从小白到大神!_哔哩哔哩_bilibili 合并行标签 初始数据透视表 不显示分类汇总 以大纲形式显示 在组的底部显示所有分类汇总 以表格形式显示 合并单元格-右键-数据透视表选项 选中-合并并剧中排列带…

吃透 Golang 基础:测试

文章目录 go test测试函数随机测试测试一个命令白盒测试外部测试包 测试覆盖率基准测试剖析示例函数 go test go test命令是一个按照一定的约定和组织来测试代码的程序。在包目录内,所有以xxx_test.go为后缀名的源文件在执行go build时不会被构建为包的一部分&#…

酒店服务配置无门槛优惠券

1.查看酒店绑定的是那个仓库; 凯里亚德酒店(深圳北站壹城中心店),绑定的是“龙华民治仓(睿嘀购” 2.“门店列表”选择“龙华民治仓(睿嘀购””中的“绑定场所” 3.通过酒店名字查找绑定的商品模板; 凯里亚德酒店(深圳…

IoT创新应用场景,赋能海外市场拓展

在数字化浪潮席卷全球的当下,物联网(Internet of Things, IoT)正以革命性的力量重塑产业生态。这项通过传感器、通信技术及智能算法实现设备互联的技术,不仅推动全球从“万物互联”迈向“万物智联”,更成为赋能企业开拓…

Idea中Docker打包流程记录

1. maven项目,先打package 2.添加Dockerfile 3.执行打包命令 注意最后的路径 . docker buildx build -t xxx-app:版本号 -f Dockerfile . 4.下载文件 docker save -o xxx-app-版本号.tar xxx-app:版本号 5.加载镜像 docker load -i xxx-app-版本号.tar 6.编…

硬件工程师笔试面试高频考点-电阻

目录 1.1 电阻选型时一般从哪几个方面进行考虑? 1.2上拉下拉电阻的作用 1.3 PTC热敏电阻作为电源电路保险丝的工作原理 1.4 如果阻抗不匹配,有哪些后果 1.5 电阻、电容和电感0402、0603和0805封装的含义 1.6 电阻、电容和电感的封装大小与什么参数有关 1.7 …

小程序入门:小程序 API 的三大分类

在小程序开发中,API(Application Programming Interface)起着至关重要的作用,它为开发者提供了丰富的功能和能力,使我们能够创建出功能强大、用户体验良好的小程序。小程序 API 大致可分为以下三大分类:事件…

算法第55天|冗余连接、冗余连接II

冗余连接 题目 思路与解法 #include <iostream> #include <vector> using namespace std; int n; // 节点数量 vector<int> father(1001, 0); // 按照节点大小范围定义数组// 并查集初始化 void init() {for (int i 0; i < n; i) {father[i] i;} } //…

Docker单独部署grafana

Docker单独部署grafana 环境说明 操作前提&#xff1a; 先去搭建PC端的MySQL和虚拟机 自行找参考 Linux部署docker参考文章&#xff1a; 02-Docker安装_docker安装包下载-CSDN博客 本文参考文章&#xff1a; 运维小记 说明&#xff1a; 本文的操作均以搭建好的PC端的MySQL和虚…