C#通过API接口返回流式响应内容---分块编码方式

1、背景

上一篇文章《C#通过API接口返回流式响应内容—SSE方式》阐述了通过SSE(Server Send Event)方式,由服务器端推送数据到浏览器。本篇是通过分块编码的方式实现

2、效果

在这里插入图片描述

3、具体代码

3.1 API端实现

[HttpGet]
public async Task ChunkedResponse()
{Response.ContentType = "text/plain";Response.Headers["Transfer-Encoding"] = "chunked"; //设置编码传输方式Response.Headers["Access-Control-Allow-Origin"] = "*"; //可以实现跨域访问//模拟DeepSeek的返回内容var phrases = new string[] { "你好!", "我是", "北京清华长庚医院", "信息管理部的", "郑林" };for (int i = 0; i < phrases.Length; i++){//1、将内容转为UTF-8编码byte[] sendContentArray = Encoding.UTF8.GetBytes(phrases[i]);//2、内容的长度var sendContentLength = sendContentArray.Length.ToString("X"); //转为16进制的标识//3、将长度内容写入到Response中var chunkedContentLength = Encoding.UTF8.GetBytes($"{sendContentLength}\r\n");await Response.Body.WriteAsync(chunkedContentLength, 0, chunkedContentLength.Length);//4、将内容与CRLF(\r\n)一起写入Response中var chunkedContentArray = Encoding.UTF8.GetBytes($"{phrases[i]}\r\n");await Response.Body.WriteAsync(chunkedContentArray, 0, chunkedContentArray.Length);await Response.Body.FlushAsync();  // 强制发送数据块await Task.Delay(1000);  // 每块之间的延时}//5、将数据终止标识写入到响应byte[] endLenghtBuffer = Encoding.UTF8.GetBytes("0\r\n");await Response.Body.WriteAsync(endLenghtBuffer, 0, endLenghtBuffer.Length);byte[] endDataBuffer = Encoding.UTF8.GetBytes("\r\n");await Response.Body.WriteAsync(endDataBuffer, 0, endDataBuffer.Length);await Response.Body.FlushAsync();//强制发送数据块
}

3.2 浏览器端的代码

<!DOCTYPE html>
<html>
<head>
<meta 
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>文档标题</title>
</head><body><div id="content"></div><script>fetch('http://localhost:5105/api/Stream/ChunkedResponse').then(response => {if (!response.ok) {console.log('异常发生!');}return response.body;}).then(stream => {console.log('进入方法');const reader = stream.getReader();const decoder =new TextDecoder();const contentDiv =document.getElementById('content');function readChunk() {reader.read().then(({ value, done }) => {if (done) {console.log('读取结束!');return;}var contentserver=decoder.decode(value, {stream:true}) //解析数据contentDiv.innerHTML+= contentserver +'&nbsp;'; //将内容追加到界面中readChunk(); //递归读取数据//setTimeout(readChunk, 100); // 也可以使用延时1秒后继续读取下一个数据块。但没有区别,大家可以试试});}readChunk(); // 启动读取流程}).catch(error => {console.error('Error:', error);});</script>
</body></html>

4、原理

4.1 代码解释

服务器端的返回(就是响应(Response))中分块编码的样例如下:

HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked25\r\n
This is the data in the first chunk\r\n1C\r\n
and this is the second one\r\n0\r\n
\r\n 

这里面包含3部分的信息
1、响应头信息中包含:Content-Type: text/plain以及Transfer-Encoding: chunked,因此在API的代码中使用了:

Response.ContentType = "text/plain";
Response.Headers["Transfer-Encoding"] = "chunked"; //设置编码传输方式

2、分块编码的数据,是放在body中,并且满足如下规则

[长度]\r\n
[数据]\r\n

(1)有两行,第一行表示长度、第二行表示数据
(2)长度为十六进制的数字,代表第二行数据的length【注意不包括\r\n
(3)每行的最后都必须有CRLF(\r\n)
(4)整个数据的最后,要以0为结尾,告知服务器,数据已经结束。即上面样例中的:

0\r\n
\r\n 

3、英文字符与中文字符的长度不一样,因此需要进行utf-8编码后,统一计算长度

4.2 前端代码说明

Fetch API是现代 Web 开发中的一个重要组成部分,它提供了一种简单且一致的方式来访问网络资源。我们要读取的内容就是Response的body,在浏览器中Response.Body是ReadableStream对象,因此可以按照流对象处理方式既可。为了实现流式输出,可以使用TransformStream 类来处理数据流,也可以使用TextDecoder直接解析。两者的却别是:前者返回一个Uint8Array数组;后者直接解析数据,更加便捷。详细的可以参考第二个参考材料。

5、参考资料

1、分块编码(Transfer-Encoding: chunked)
2、fetch实现流式输出的实现原理

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

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

相关文章

SSL 原理及实验

引言 为了实现远程办公或者远程客户访问内网的资源 &#xff08;1&#xff09;回顾历史&#xff1a; 起初先出现SSL(Secure Sockets Layer&#xff09;&#xff0d;安全套接层协议。 美国网景Netscape公司1994年研发&#xff0c;介于传输层TCP协议和应用层协议之间的一种协议…

C++ 布尔类型(bool)深度解析

引言 在 C 编程里&#xff0c;布尔类型&#xff08;bool&#xff09;是一种基础且极为关键的数据类型。它专门用于表达逻辑值&#xff0c;在程序的条件判断、循环控制等诸多方面都发挥着重要作用。接下来&#xff0c;我们将对 C 中的布尔类型展开全面且深入的探讨。 一、布尔…

UE5.5 Niagara发射器更新属性

发射器属性 在 Niagara 里&#xff0c;Emitter 负责控制粒子生成的规则和行为。不同的 Emitter 属性决定了如何发射粒子、粒子如何模拟、计算方式等。 发射器 本地空间&#xff08;Local Space&#xff09; 控制粒子是否跟随发射器&#xff08;Emitter&#xff09;移动。 ✅…

各省水资源平台 水资源遥测终端机都用什么协议

各个省水资源平台 水资源遥测终端机 的建设大部分从2012年开始启动&#xff0c;经过多年建设&#xff0c;基本都已经形成了稳定的通讯要求&#xff1b;河北瑾航科技 遥测终端机&#xff0c;兼容了大部分省市的通讯协议&#xff0c;如果需要&#xff0c;可以咨询和互相学习&…

使用OpenCV和MediaPipe库——抽烟检测(姿态监控)

目录 抽烟检测的运用 1. 安全监控 (1) 公共场所禁烟监管 (2) 工业安全 2. 智能城市与执法 (1) 城市违章吸烟检测 (2) 无人值守管理 3. 健康管理与医疗 (1) 吸烟习惯分析 (2) 远程监护 4. AI 监控与商业分析 (1) 保险行业 (2) 商场营销 5. 技术实现 (1) 计算机视…

WPF窗口读取、显示、修改、另存excel文件——CAD c#二次开发

效果如下&#xff1a; using System.Data; using System.IO; using System.Windows; using Microsoft.Win32; using ExcelDataReader; using System.Text; using ClosedXML.Excel;namespace IfoxDemo {public partial class SimpleWindow : Window{public SimpleWindow(){Initi…

HarmonyOS NEXT - 电商App实例三( 网络请求axios)

使用axios开发网络请求是一个非常常见的任务&#xff0c;尤其是Web前端开发者&#xff0c;对它非常熟悉。axios是一个基于Promise的HTTP客户端&#xff0c;支持浏览器和Node.js环境&#xff0c;使用简单且功能强大。 在harmonyOS中&#xff0c;如果想使用axios&#xff0c;可以…

生成省市区JSON

省市区 学习记录 https://xiangyuecn.github.io/AreaCity-JsSpider-StatsGov/ package cn.serverx.sx.your;import cn.hutool.core.io.FileUtil; import cn.serverx.sx.your.vo.DistrictNode; import com.alibaba.fastjson2.JSON; import com.google.common.collect.Lists; i…

医疗APP开发如何实现跨机构数据互通

医疗APP开发如何实现跨机构数据互通 在数字化医疗时代,医疗APP开发已成为连接医疗机构、患者和医疗资源的重要桥梁。然而,如何实现跨机构的数据互通,成为医疗APP开发中的一大挑战。本文将探讨如何通过医疗APP开发实现跨机构数据互通,提升医疗服务效率和患者体验。我们将涵…

自定义Linux网络协议的开发与测试

在当今快速发展的技术领域中,定制化网络协议可以为特定的应用场景提供灵活而强大的解决方案。本文将详细介绍如何在Linux系统上开发一个自定义网络协议,并编写相应的用户空间程序进行测试。所有步骤基于2025年3月11日的时间点完成。 开发自定义协议内核模块 定义协议和实现…

PySide(PyQT)的mouseMoveEvent()和hoverMoveEvent()的区别

在 PySide中&#xff0c;mouseMoveEvent 和 hoverMoveEvent 都是用于处理鼠标移动相关操作的事件&#xff0c;但它们之间存在明显的区别&#xff1a; 事件触发条件 • mouseMoveEvent&#xff1a; 当鼠标在对应的图形项&#xff08;如 QGraphicsPixmapItem&#xff09…

级联树SELECTTREE格式调整

步骤&#xff1a; 1、将全部列表设置成Map<Long, List<Obejct>> map的格式&#xff0c;方便查看每个父级对应的子列表&#xff0c;减少循环次数 2、对这个map进行递归&#xff0c;重新进行级联树的集合调整&#xff0c;将子集放置在对应的childs里面。 public Dyna…

详解数据库范式

范式 1. 第一范式&#xff08;1NF&#xff09;2. 第二范式&#xff08;2NF&#xff09;3. 第三范式&#xff08;3NF&#xff09;4. BC范式&#xff08;BCNF&#xff0c;Boyce-Codd Normal Form&#xff09;5. 第四范式&#xff08;4NF&#xff09;6. 第五范式&#xff08;5NF&a…

一窥DeepSeek开源EPLB项目:揭开技术背后的面纱

摘要 在DeepSeek开源DualPipe项目的同一天&#xff0c;EPLB项目也正式对外公开。EPLB&#xff08;Enhanced Pipeline Balancing&#xff09;并非一蹴而就的奇迹&#xff0c;而是经过长时间的研发与优化。该项目旨在通过改进管道平衡机制&#xff0c;提升系统的稳定性和效率。本…

Unity进阶课程【二】Mask 组件的使用 UI遮罩效果以及透明抠图效果

Unity组件讲解 Mask 时隔多年&#xff0c;今天咱们继续进阶课程&#xff0c;这几年变化很大&#xff0c;但是一直还是从事Unity行业&#xff0c;行业虽难&#xff0c;依旧坚持&#xff0c;以后会养成习惯&#xff0c;定期更新&#xff0c;希望小伙伴们监督&#xff0c;有想学习…

汽车无钥匙启动系统不使用传统机械钥匙启动汽车

汽车无钥匙启动系统 定义 汽车无钥匙启动系统&#xff08;Keyless Start System&#xff09;&#xff0c;启动车辆时不用掏拧钥匙&#xff0c;只需把钥匙放在包内或口袋里&#xff0c;按下车内按键或拧动导板即可使发动机点火。它无需插入钥匙&#xff0c;通过点按按键或旋转…

Webpack 和 Vite 的主要区别

Webpack 和 Vite 的主要区别&#xff0c;从构建机制、开发体验、生产优化等多个维度进行对比&#xff1a; 1. 构建机制与速度 Webpack 全量打包&#xff1a;启动时必须分析所有模块依赖关系&#xff0c;进行全量打包&#xff0c;生成 Bundle 文件。项目越大&#xff0c;冷启动时…

【Python】Python 3.11安装教程

一、Python 3.11安装包下载 1. Python 3.11下载与安装 Download Python | Python.org 下载完成包含以下文件&#xff1a; 二、python3.11安装步骤 1.右键以管理员身份运行安装程序。 2.勾选【Add Python…】然后点击【Customize…】。 3.页面点击【Next】。 4.勾选【Install …

如何处理PHP中的编码问题

如何处理PHP中的编码问题 在PHP开发过程中&#xff0c;编码问题是一个常见且棘手的问题。无论是处理用户输入、数据库交互&#xff0c;还是与外部API通信&#xff0c;编码问题都可能导致数据乱码、解析错误甚至安全漏洞。本文将深入探讨PHP中的编码问题&#xff0c;并提供一些…

【毕业论文格式】word分页符后的标题段前间距消失

文章目录 【问题描述】 分页符之后的段落开头&#xff0c;明明设置了标题有段前段后间距&#xff0c;但是没有显示间距&#xff1a; 【解决办法】 选中标题&#xff0c;选择边框 3. 选择段前间距&#xff0c;1~31磅的一个数 结果