ASP.NET Core Web API 流式返回,逐字显示
Websocket、SSE(Server-Sent Events)和长轮询(Long Polling)都是用于网页和服务端通信的技术。
Websocket是一种全双工通信协议,能够实现客户端和服务端之间的实时通信。它基于TCP协议,并且允许服务器主动向客户端推送数据,同时也允许客户端向服务器发送数据。
SSE是一种单向通信协议,允许服务器向客户端推送数据,但不支持客户端向服务器发送数据。SSE建立在HTTP协议上,通过在HTTP响应中使用特殊的Content-Type和事件流(event stream)格式来实现。
长轮询是一种技术,客户端向服务器发送一个请求,并且服务器保持连接打开直到有数据可以返回给客户端。如果在指定的时间内没有数据可用,则服务器会关闭连接,客户端需要重新建立连接并再次发起请求。
New Bing聊天页面是通过WebSocket进行通信。

Open AI的ChatGPT接口则是通过SSE协议由服务端推送数据

事实上,以上几种方式包括长轮询,都可以实现逐字显示的效果。那还有没有其他的办法可以实现这种效果了呢?
流式响应
当客户端返回流的时候,客户端可以实时捕获到返回的信息,并不需要等全部Response结束了再处理。
下面就用ASP.NET Core Web API作为服务端实现流式响应。
返回文本内容
服务端
[HttpPost("text")]
public async Task Post()
{
string filePath = "文档.txt";
Response.ContentType = "application/octet-stream";
var reader = new StreamReader(filePath);
var buffer = new Memory<char>(new char[5]);
int writeLength = 0;
//每次读取5个字符写入到流中
while ((writeLength = await reader.ReadBlockAsync(buffer)) > 0)
{
if (writeLength < buffer.Length)
{
buffer = buffer[..writeLength];
}
await Response.WriteAsync(buffer.ToString());
await Task.Delay(100);
}
}
客户端
- C# HttpClient
public async void GetText()
{
var url = "http://localhost:5000/config/text";
var client = new HttpClient();
using HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, url);
var response = await client.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseHeadersRead);
await using var stream = await response.Content.ReadAsStreamAsync();
var bytes = new byte[20];
int writeLength = 0;
while ((writeLength = stream.Read(bytes, 0, bytes.Length)) > 0)
{
Console.Write(Encoding.UTF8.GetString(bytes, 0, writeLength));
}
Console.WriteLine();
Console.WriteLine("END");
}
HttpCompletionOption枚举有两个值,默认情况下使用的是ResponseContentRead
ResponseContentRead:等到整个响应完成才完成操作ResponseHeadersRead:一旦获取到响应头即完成操作,不用等到整个内容响应

- js XMLHttpRequest
<script>
var div = document.getElementById("content")
var url = "http://localhost:5000/config/text"
var client = new XMLHttpRequest()
client.open("POST", url)
client.onprogress = function (progressEvent) {
div.innerText = progressEvent.target.responseText
}
client.onloadend = function (progressEvent) {
div.append("END")
}
client.send()
</script>
用axios请求就是监听onDownloadProgress 了。
浏览器是通过
Response Header中的Content-Type来解析服务端响应体的。如果后端接口没有设置Response.ContentType = "application/octet-stream",onprogress只会在响应全部完成后触发。

返回图片
服务端
[HttpGet("img")]
public async Task Stream()
{
string filePath = "pixelcity.png";
new FileExtensionContentTypeProvider().TryGetContentType(filePath, out string contentType);
Response.ContentType = contentType ?? "application/octet-stream";
var fileStream = System.IO.File.OpenRead(filePath);
var bytes = new byte[1024];
int writeLength = 0;
while ((writeLength = fileStream.Read(bytes, 0, bytes.Length)) > 0)
{
await Response.Body.WriteAsync(bytes, 0, writeLength);
await Task.Delay(100);
}
}

ASP.NET Core Web API 流式返回,逐字显示的更多相关文章
- ASP.NET Core Web API下事件驱动型架构的实现(二):事件处理器中对象生命周期的管理
在上文中,我介绍了事件驱动型架构的一种简单的实现,并演示了一个完整的事件派发.订阅和处理的流程.这种实现太简单了,百十行代码就展示了一个基本工作原理.然而,要将这样的解决方案运用到实际生产环境,还有很 ...
- ASP.NET Core WEB API 使用element-ui文件上传组件el-upload执行手动文件文件,并在文件上传后清空文件
前言: 从开始学习Vue到使用element-ui-admin已经有将近快两年的时间了,在之前的开发中使用element-ui上传组件el-upload都是直接使用文件选取后立即选择上传,今天刚好做了 ...
- ASP.NET Core Web API 教程 - Project Configuration
ASP.NET Core Web API 教程 本系列文章主要参考了<Ultimate ASP.NET Core 3 Web API>一书,我对原文进行了翻译,同时适当删减.修改了一部分内 ...
- 在 ASP.NET Core Web API中使用 Polly 构建弹性容错的微服务
在 ASP.NET Core Web API中使用 Polly 构建弹性容错的微服务 https://procodeguide.com/programming/polly-in-aspnet-core ...
- 使用 Swagger 自动生成 ASP.NET Core Web API 的文档、在线帮助测试文档(ASP.NET Core Web API 自动生成文档)
对于开发人员来说,构建一个消费应用程序时去了解各种各样的 API 是一个巨大的挑战.在你的 Web API 项目中使用 Swagger 的 .NET Core 封装 Swashbuckle 可以帮助你 ...
- Docker容器环境下ASP.NET Core Web API应用程序的调试
本文主要介绍通过Visual Studio 2015 Tools for Docker – Preview插件,在Docker容器环境下,对ASP.NET Core Web API应用程序进行调试.在 ...
- 在docker中运行ASP.NET Core Web API应用程序
本文是一篇指导快速演练的文章,将介绍在docker中运行一个ASP.NET Core Web API应用程序的基本步骤,在介绍的过程中,也会对docker的使用进行一些简单的描述.对于.NET Cor ...
- 在Mac下创建ASP.NET Core Web API
在Mac下创建ASP.NET Core Web API 这系列文章是参考了.NET Core文档和源码,可能有人要问,直接看官方的英文文档不就可以了吗,为什么还要写这些文章呢? 原因如下: 官方文档涉 ...
- ASP.NET Core Web API 开发-RESTful API实现
ASP.NET Core Web API 开发-RESTful API实现 REST 介绍: 符合REST设计风格的Web API称为RESTful API. 具象状态传输(英文:Representa ...
- Docker容器环境下ASP.NET Core Web API
Docker容器环境下ASP.NET Core Web API应用程序的调试 本文主要介绍通过Visual Studio 2015 Tools for Docker – Preview插件,在Dock ...
随机推荐
- cv2安装
pip install opencv-contrib-python
- 安装win10:我们无法创建新的分区,也无法定位现有分区
操作环境:win10企业版ISO,U盘安装,UEFI启动 解决思路:win10 UEFI 安装需要硬盘在GPT模式,如果直接创建分区默认的是MBR,所以将磁盘转换成GPT,再分配一个EFI空白分区,就 ...
- 修改word文档中已有的批注者名称
前言 https://blog.csdn.net/hyh19962008/article/details/89430548 word中可以通过修改用户的信息实现新建的批注者显示不同的名称,但是对于文档 ...
- C语言和C++的区别与联系(详细)
文章转自:https://blog.csdn.net/cherrydreamsover/article/details/81835976 在学习了C语言和C++之后,这两者之间的区别我们需要仔细的捋一 ...
- Adams-STEP函数
1 给运动添加函数 例1: step(time,0,0,2,30d) 表示:当0秒时位移为0°,当2秒时位移为30°. 例2: step(time,0,0,0.6,1.7) +step(time,0. ...
- 安装单机版k8s
1.配置yum源,博主使用华为的镜像源 选择不同的系统版本下载使用: 2.安装etcd,kubernetes yum -y install etcd kubernetes 3.修改kubernetes ...
- Mitmproxy 拦截、mock移动设备网络请求
转载于https://blog.csdn.net/countofdane/article/details/82055173 1. 安装 pip install mitmproxy 2. 启动 mi ...
- final修饰的作用
在Java中,final关键字可以用来修饰类.方法和变量(包括成员变量和局部变量) 1.final修饰类 当用final修饰一个类时,表明这个类不能被继承. final类中的成员变量可以根据需要设为f ...
- Android笔记--基础的连接数据库的操作
start.java package com.example.myapplication; import androidx.activity.result.ActivityResult; import ...
- Salesforce CPQ之后续慢慢看系列
salesforce核心两朵云,sales & service. 针对sales的quote / quote line item的报价功能,还是相对薄弱.针对sales,报价的准确性影响着成单 ...