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 ...
随机推荐
- vim入门与快捷键使用
1.移动 上下左右 jkhl 2.模式选择 命令模式 插入模式 字符选择模式 3.剪切复制 粘贴:p 复制 y 选择 v 进入选择模式 4. 撤销恢复 撤销 u 恢复 ctrl + r 5. 删除 d ...
- Matlab字体设置中找不到字体的解决方法(转载)
Matlab字体设置中找不到字体 Matlab默认的字体实在不好看,一般都需要重新设置字体. 在其字体设置中有些字体不能同时支持中文和英文,我在之前的博客中说过,如何为Matlab设置一款好看的同时兼 ...
- Java学习笔记(二)环境
卸载JDK 1.删除java的安装目录 2.删除JAVA_HOME 3.删除path下关于java的目录 4.java -version 配置环境变量 1.我的电脑-->右键-->属性 ...
- nRF52832出现“APP_UART_COMMUNICATION_ERROR”的错误的问题
在调试nRF52832的uart的过程中,发现调试信息会时不时打印"APP_UART_COMMUNICATION_ERROR"这个错误,看上去似乎毫无规律.查看SDK的相关说明,可 ...
- python语言linux操作系统oracle环境安装
金句:如果没把握,最好先Google一下. 1.严格按照 https://oracle.github.io/odpi/doc/installation.html#linux 教程一步步做 包括下载的软 ...
- Spyglass CDC工具使用(二)
最近一直在搞CDC (clock domain crossing) 方面的事情,现在就CDC的一些知识点进行总结. 做CDC检查使用的是Spyglass工具.以下内容转载自:Spyglass检查之CD ...
- 自定义配置Springboot内嵌的tomcat
两种方法都可以:例子:在tomcat里添加MIME类型,application/wasm 1. import org.springframework.boot.web.embedded.tomcat. ...
- LaTeX in 24 Hours - 书籍信息
书籍信息 书名: LaTex in 24 Hours: A Practical Guide for Scientific Writing 作者: Dilip Datta 出版日期: 2017 ISBN ...
- Hive中的高级函数
高级函数 1.炸裂函数 UDTF 通常是将数组或者集合中或者结构体(涉及到数据类型-------复杂数据类型)中的元素单个输出 特点:接收一行数据,输出一行或多行数据 2.窗口函数/开窗函数 概念:能 ...
- mysql基础知识&&常用命令
了解 什么是数据库?什么是数据管理系统?什么是SQL,他们之间的关系又是什么? 数据库 英文单词DataBase,简称DB,按照一定格式存储数据的一些文件的组合. 顾名思义:存储数据的仓库,实际上就是 ...