AspNetCore 实战:三种流式响应机制详解

news/2025/2/11 11:17:01/文章来源:https://www.cnblogs.com/netcore5/p/18709401

在现代Web应用中,实时数据传输和高效的数据流处理变得越来越重要。AspNetCore 提供了多种流式响应机制,以满足不同场景下的需求。

在使用ChatGpt,deepseek的适合有没有想过ai的逐字显示回答是怎么实现的,下面将介绍三种主要的流式响应来实现此功能。

Server-Sent Events (SSE)

Server-Sent Events (SSE) 是一种允许服务器主动向客户端推送数据的机制,适用于实时更新的应用(如聊天应用、实时监控、新闻推送等)。

通过设置Content-Type: text/event-stream来使用SSE协议,客户端就能实时接收服务器发送的消息。

服务器端:

using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;namespace StreamedResponseExample.Controllers
{[Route("api/[controller]")][ApiController]public class StreamController : ControllerBase{[HttpGet("sse")]public async Task StreamSse(){Response.ContentType = "text/event-stream";Response.Headers.Add("Cache-Control", "no-cache");Response.Headers.Add("Connection", "keep-alive");var messages = new string[] { "Hello, ", "this is an SSE message!", "Here's another message." };foreach (var message in messages){await Response.WriteAsync($"data: {message}\n\n");await Response.Body.FlushAsync();  // 强制立即发送await Task.Delay(1000);  // 每条消息间隔1秒}}}
}

客户端-html:

<div id="messages"></div><script>// 创建SSE连接const eventSource = new EventSource('https://localhost:7148/WeatherForecast/sse');// 监听消息事件eventSource.onmessage = function (event) {const messageContainer = document.getElementById('messages');const newMessage = document.createElement('p');newMessage.textContent = event.data;messageContainer.appendChild(newMessage);// 滚动到最新消息messageContainer.scrollTop = messageContainer.scrollHeight;};// 监听打开连接事件eventSource.onopen = function () {console.log("连接已打开");};// 监听错误事件eventSource.onerror = function (error) {console.error("发生错误", error);eventSource.close(); // 关闭连接};</script>

说明:

  • Response.ContentType = "text/event-stream":设置响应的类型为SSE。
  • 通过 data: {message}\n\n 格式发送消息,每次都以“data:”开头。
  • 使用EventSource API在客户端接收事件流。

SSE是一种轻量级且简单的流式响应方式,尤其适用于向客户端推送消息的场景,如实时数据更新。

WebSocket

WebSocket 是一种全双工通信协议,适用于需要双向实时通信的应用,如在线聊天、多人游戏等。优势在于可以同时接收和发送消息,且没有HTTP请求/响应的开销。

通过WebSocket,客户端和服务器之间建立持久连接,双向传输消息。

使用WebSocket进行流式传输服务器端:

using Microsoft.AspNetCore.SignalR;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;namespace StreamedResponseExample.Controllers
{public class ChatHub : Hub{public async Task SendMessage(string message){await Clients.All.SendAsync("ReceiveMessage", message);}}[Route("api/[controller]")][ApiController]public class StreamController : ControllerBase{private readonly IHubContext<ChatHub> _hubContext;public StreamController(IHubContext<ChatHub> hubContext){_hubContext = hubContext;}[HttpGet("websocket")]public async Task WebSocketStream(){var messages = new string[] { "Hello, ", "this is a WebSocket message!", "Here's another one." };foreach (var message in messages){await _hubContext.Clients.All.SendAsync("ReceiveMessage", message);await Task.Delay(1000);  // 每条消息间隔1秒}}}
}

客户端:

const connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();connection.on("ReceiveMessage", function (message) {console.log("Received message: ", message);
});connection.start().catch(function (err) {return console.error(err.toString());
});
  • WebSocket的优点在于能够进行实时的双向通信,适用于需要交互的场景。
  • 使用SignalR库可以简化WebSocket的实现,SignalR封装了WebSocket等协议,提供了更易用的API。

Chunked Transfer Encoding (分块传输编码)

分块传输编码是HTTP/1.1的一种机制,它允许服务器以多个“块”的形式将响应数据发送给客户端。客户端接收到每个块后可以立即处理,而不是等待所有数据传输完成。

ASP.NET Core默认支持分块传输编码,当响应体的内容未知时,分块传输会自动启用。

使用分块传输编码(Chunked Encoding)服务器端:

using Microsoft.AspNetCore.Mvc;
using System.Text;
using System.Threading.Tasks;namespace StreamedResponseExample.Controllers
{[Route("api/[controller]")][ApiController]public class StreamController : ControllerBase{[HttpGet("chunked")]public async Task ChunkedResponse(){Response.ContentType = "text/plain";var phrases = new string[] { "This is ", "a chunked ", "response! ", "Enjoy it." };foreach (var phrase in phrases){byte[] buffer = Encoding.UTF8.GetBytes(phrase);await Response.Body.WriteAsync(buffer, 0, buffer.Length);await Response.Body.FlushAsync();  // 强制发送数据块await Task.Delay(1000);  // 每块之间的延时}}}
}

客户端:
客户端可以像普通HTTP请求一样使用fetchXMLHttpRequest接收分块数据,并逐步处理每个数据块。

<body><div id="content"></div><script>fetch('https://localhost:7128/WeatherForecast/ChunkedResponse/chunked').then(response => {const reader = response.body.getReader();const decoder = new TextDecoder();const contentDiv = document.getElementById('content');function readChunk () {reader.read().then(({ done, value }) => {if (done) return;contentDiv.innerHTML += decoder.decode(value, { stream: true }) + '<br>';readChunk();  // 继续读取下一个数据块});}readChunk();});</script>
</body>

说明:

  • 分块传输编码:这是HTTP协议中的一个标准机制。它可以在响应数据还没有完全生成时就开始传输,这样客户端可以逐步接收并处理数据。

结论:

  • SSE:适合服务器向客户端推送数据(单向流)专门用于事件推送。
  • WebSocket:适合需要双向实时通信的应用。
  • 分块传输编码:适合大数据流的分块传输,支持逐步发送响应。

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

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

相关文章

java中反射-字节码和类加载器

多态的一个表现 子类类型赋值给父类 Father f1 = New Son() 调用子类方法报错。 调用父类方法OK。这个就是多态 一个对象能用什么方法,并不是取决于 它有什么方法。 而是取决于引用变量的类型(也就是取决于它声明的类型,Father类型) 它能够用的方法,一定是Father中的方法。 …

本地私有化部署DeepSeek,打造自己的大模型知识库

1简介 DeepSeek R1是基于MIT协议开源的大模型,意味着个人和企业可以免费使用,包括商业使用。 众所周知,我们可以在chat.deepseek.com上可以直接免费使用DeepSeek R1的聊天服务。但如果你自己开发的应用需要使用到其api的话,仍然是需要收费的,另外,如果你有机密信息并不想…

五. 数据库

数据库 一. 三级模式 一个数据库可以有多个外模式,只能有一个内模式。 视图对应外模式、基本表对应模式、存储文件对应内模式二. 两级映像 (1) 模式/内模式映像。存在于概念级和内部级之间,实现了概念模式和内模式之间的相互转换。 (2) 外模式/模式映像。存在于外部级和概念级…

Oracle 缩容量方法 --转发 https://www.modb.pro/db/1873006442018521088?utm_source=index_ai

1.系统表空间清理 SYSAUX表空间被称为系统辅助表空间,主要的目的是为SYSTEM表空间减负。1.1 表空间的使用率 比如大表大部分都是AUD$和WRH$开头的AWR基表,AUD$使用SYSTEM表空间,AWR的基表使用SYSAUX表空间。 SELECT df.tablespace_name, COUNT (*) datafile_count,ROUND (SUM…

轻松上手!小白必看:在你的个人电脑上安装DeepSeek R1 大模型

deepseek本地化部署,小白教程,让你的个人电脑也能安装运行大模型!一、deepseek简介 DeepSeek是一个强大的工具,它就像一个聪明的助手,能帮我们处理和分析大量信息。它适用于各种场合,比如理解文字、识别图片,还能根据你的喜好推荐东西。 这个工具很灵活,就像乐高积木,…

macOS Sequoia 15.3.1 (24D70) 正式版 ISO、IPSW、PKG 下载

macOS Sequoia 15.3.1 (24D70) 正式版 ISO、IPSW、PKG 下载macOS Sequoia 15.3.1 (24D70) 正式版 ISO、IPSW、PKG 下载 iPhone 镜像、Safari 浏览器重大更新和 Apple Intelligence 等众多全新功能令 Mac 使用体验再升级 请访问原文链接:https://sysin.org/blog/macOS-Sequoia/…

macOS Sequoia 15.3.1 (24D70) Boot ISO 原版可引导镜像下载

macOS Sequoia 15.3.1 (24D70) Boot ISO 原版可引导镜像下载macOS Sequoia 15.3.1 (24D70) Boot ISO 原版可引导镜像下载 iPhone 镜像、Safari 浏览器重大更新和 Apple Intelligence 等众多全新功能令 Mac 使用体验再升级 请访问原文链接:https://sysin.org/blog/macOS-Sequoi…

如何利用看板工具,让项目进度一目了然?

使用看板评估项目进度需要经历准备、实施、评估与分析以及持续改进与优化等多个阶段。通过合理利用看板工具,团队可以更加高效地管理项目进度,提高项目管理的透明度和协作效率。看板工具最早起源于20世纪50年代的日本丰田生产系统,如今已被广泛应用于软件开发、产品管理、市…

ABB IRB360并联机器人|abb蜘蛛手维修

ABB IRB360并联机器人(也被称为蜘蛛手机器人)发挥着极为重要的作用。然而,如同所有的机械设备一样,它也会面临需要维修的情况。对ABB IRB360并联机器人进行有效的维修不仅能延长其使用寿命,还能确保工业生产的高效进行。一、ABB IRB360并联机器人的结构与常见故障1. 结构特…

为何焦点已从 AI 代理转向AI辅助人类工作模式

前言:随着AI技术的发展,AI行业从AI代理转向了‘AI辅助人类工作模式’。虽然AI代理在演示中很有潜力,但在实际使用时,它的准确性和可靠性远低于人类,限制了它的应用。相反,‘AI辅助人类工作模式’通过将复杂任务拆分成小步骤,帮助人类更高效地完成工作,推动了数据整理和…

CentOS7 离线安装docker环境

1、系统要求 首先需要确定 CentOS7 的内核版本号,因为 docker 安装要求 Linux 内核版本在 3.10 及以上。查看内核版本号: uname -r查看系统名称: cat /etc/redhat-release2、下载Docker Docker官网:Docker: Accelerated Container Application Development Docker引擎安装说…

烟草行业如何用低代码+ BI 实现数字化转型?

在数字经济的大潮中,烟草行业正迎来重大的发展契机。国家层面的政策引导和战略规划为行业的数字化转型提供了明确的方向。《数字中国》的愿景逐步变为现实,国家信息化发展战略的深入推进,为烟草行业的智能化、网络化发展提供了强劲的动力。基于全国烟草工作会议重点的指导方…