前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >C# 使用IAsyncEnumerable实现流式分段传输

C# 使用IAsyncEnumerable实现流式分段传输

作者头像
郑子铭
发布于 2023-10-29 08:13:15
发布于 2023-10-29 08:13:15
60900
代码可运行
举报
运行总次数:0
代码可运行

前言

在使用SSE的时候,前端可以实现流式传输,但是有个问题就是这是一个独占的连接,相当于如果你不手动关闭连接,就会一直请求,一直连接调用接口,而且发送的数据格式也是按照定义好的协议来

而使用C#自带的IAsyncEnumerable也可以实现流式传输,不过返回的数据是在之前返回的基础上进行累加,需要自己做处理,我的例子是使用的是ajax来实现,群友有提供了fetch的实现代码,接下来我们看看c#IAsyncEnumerable实现传输的ajax方案和fetch的代码吧。

AJAX

下面是源码和gif效果展示,可以看到我们返回的是一个IAsyncEnumerable< int>类型的结果,在第二段代码,我们都知道ajax是根据xhrhttprequest封装的,所以自然也可以用一些它的一些事件,所以我们在此处用了onprogress来监听我们请求的进度,在这里我们就可以获取到每一次写了哪些东西,从而实现一个流传输,因为后端写也是一个字节一个字节去写的,前端接收也是如此。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[HttpGet("Postb")]
public async IAsyncEnumerable<int> PostB()
{
    await foreach (var item in  GetData())
     {
         yield return item;
     }
 }
private async IAsyncEnumerable<int> GetData()
{
      foreach (int item in Enumerable.Range(0,100))
      {
          await Task.Delay(100);
          yield return item;
      }
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html >
<html>
<head>
    <title>AJAX Example</title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script>

        function callAjax() {
            $.ajax({
                url: 'http://localhost:5203/WeatherForecast/Postb',
    method: 'GET',
    contentType: 'application/json',
    xhrFields: {
      onprogress: function (e) {
        var msg = e.currentTarget.response;
        $("#list").append(`<h5>${msg}</h5>`);
        console.log("接收的数据是=>" + msg);
        },
        onchange: function (a) {
            debugger;
        }
    },
    success: function () {
      console.log("分块读取完成");
    },
    error: function (xhr, status, error) {
      console.log("请求失败");
      console.log("错误信息: " + error);
    }
  });
        }
    </script>
</head>
<body>
    <button onclick="callAjax()">调用AJAX</button>
</body>
</html>

SSE

SSE全称Server Sent Event,从名字我们可以看出,这是一个服务端单向发送到客户端的,与WebSocket不同,但是两者都是长连接,上面的ajax的响应标头是applycation/json,SSE的必须是text/event-stream,并且SSE的发送的参数也都是有固定的格式,每一个发送的消息都是由\n\n分割,每一个message由若干个可选的字段组成;

例如下面,field:value是一个message里面的内容,field可选范围是下面那四个,第二代码段是后端的代码,展示了一个完整的message,包括了data,event,retry和id,其中上面,我们设置了响应的Content-type是text/event-stream,设置是不缓存no-cache,下面设置是保持连接,keepalive,因为是长连接嘛,id和data可以随便给,retry是端口连接后的一个重新连接时间,event是一个事件的名称,我们给客户端返回这个格式的内容,客户端就会根据这个内容就返回数据,调用我们的event,从而实现一个流式输出。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[field]: value\n  //这是一个Message
//下面是可选的字段
data
event
id
retry
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[HttpGet("Posta")]
public  IActionResult Posta()
{
     if (Response.Headers.ContainsKey("Content-Type"))
     {
         Response.Headers.Remove("Content-Type");
         Response.Headers.Add("Content-Type", "text/event-stream");
     }
     else
     {
         Response.Headers.Add("Content-Type", "text/event-stream");
     }
     Response.Headers.Add("Cache-Control", "no-cache");
     Response.Headers.Add("Connection", "keep-alive");
     string data =
               $"id: {Random.Shared.Next()} \n" +
               $"retry: {Random.Shared.Next(0, 100) * 30}\n" +
               $"event: message\n" +
               $"data: {Random.Shared.Next()}\n\n";return Content(data);
 }
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html>
<head>
    <title>SSE Example</title>
    <script>
        var eventSource = new EventSource("http://localhost:5203/WeatherForecast/Posta");  
        eventSource.addEventListener("message", function(event) {
var a=document.getElementById("aaa");
a.innerHTML+="<a>"+event.data+"</a><br>"
            console.log("Received message: " + event.data);
        });
        eventSource.addEventListener("error", function(event) {
            console.log("Error occurred");
        });
    </script>
</head>
<body>
<div id='aaa'></div>
</body>
</html>

总结

以上便是全部内容,当然,图片的流式传输,返回html然后显示,也可以直接去给响应流写数据,content-type是stream的形式,会一点一点的加载,感兴趣的朋友可以自己手动尝试一下。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-10-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DotNet NB 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【流式传输】使用Spring Boot实现ChatGpt流式传输
    在ChatGpt火了这么久,他的那种单字单字返回的格式可能让很多朋友感到好奇,在之前我用c#写了一个版本的,同时支持IAsyncEnumerable以及SSE,今天把之前写的Java版本的也发出来,和大家一起学习,有不对的地方,欢迎各位大佬指正。
陈显达
2023/12/20
1.7K0
【流式传输】使用Spring Boot实现ChatGpt流式传输
AspNetCore 实战:三种流式响应机制详解
在现代Web应用中,实时数据传输和高效的数据流处理变得越来越重要。AspNetCore 提供了多种流式响应机制,以满足不同场景下的需求。
郑子铭
2025/03/27
1220
AspNetCore 实战:三种流式响应机制详解
了解ChatGPT流式响应背后的技术,优化数据流处理效率!
我们知道 ,ChatGPT API是一个OpenAI 的聊天机器人接口,它可以根据用户的输入生成智能的回复。为了提高聊天的流畅性和响应速度,ChatGPT API采用了SSE作为服务端推送技术。SSE是一种HTML5技术,它允许服务器向客户端发送事件,从而实现服务器端推送。相对于WebSockets或长轮询技术,SSE提供了更简单的方式来实现服务器端推送,并且支持更广泛的客户端和服务器端。
老码小张
2023/05/06
10.4K3
了解ChatGPT流式响应背后的技术,优化数据流处理效率!
SSE请求多种实现方式总结(干货分享)
SSE(Server-Sent Events)是一种用于实现服务器主动向客户端推送数据的技术,也被称为“事件流”(Event Stream)。它基于 HTTP 协议,利用了其长连接特性,在客户端与服务器之间建立一条持久化连接,并通过这条连接实现服务器向客户端的实时数据推送。
用户10501441
2024/11/24
2.5K0
通信方式进阶
腾讯IVWEB团队
2017/07/05
2.1K0
通信方式进阶
服务端事件EventSource揭秘
服务端推 服务端推,指的是由服务器主动的向客户端发送消息(响应)。在应用层的HTTP协议实现中,“请求-响应”是一个round trip,它的起点来自客户端,因此在应用层之上无法实现简易的服务端推功能。当前解决服务端推送的方案有这几个: 客户端长轮询 websocket双向连接 iframe永久帧 长轮训虽然可以避免短轮训造成的服务端过载,但在服务端返回数据后仍需要客户端主动发起下一个长轮训请求,等待服务端响应,这样仍需要底层的连接建立而且服务端处理逻辑需要相应处理,不符合逻辑上的流程简单的服务端推送; w
欲休
2018/03/15
2.6K0
Uniapp仿ChatGPT Stream流式输出(非Websocket)-uniapp+see接收推送示例
最近写一个chagpt小程序,流式输出可以使用websocket也可以使用stream来实现,这里就不折腾websocket的了,我发现uniapp实现流式输出的方式挺多的,主要是有些小程序还不兼容,花了点时间研究了一下。
超级小可爱
2024/03/26
3.8K0
高性能PHP框架webman服务端实现流式输出有哪些解决方案?
Stream流式输出是一种数据处理方式,它将数据以流的形式进行传输和处理。在这种处理方式中,数据不再是集中存储在某个地方,而是以分散的方式存储在各个节点上,并不断流动。数据流的处理是在流动的过程中完成的,因此能够实时地处理数据,提高了数据处理效率。
Tinywan
2024/11/21
2590
高性能PHP框架webman服务端实现流式输出有哪些解决方案?
Comet,SSE,WebSocket前后端的实现
Comet(服务器推送)的两种方式 短轮询 页面定时向服务器发送请求, 步骤为:建立连接——数据传输——关闭连接...建立连接——数据传输——关闭连接 //前端js var xhr = new XMLHttpRequest(); setInterval(()=>{ xhr.onreadystatechange = function () { if (xhr.readyState == 4) { let result = xhr.responseText
chuchur
2022/10/25
8510
SSE eventSource简介
eventSource是用来解决web上服务器端向客户端推送消息的问题的。不同于ajax轮询的复杂和websocket的资源占用过大,eventSource(sse)是一个轻量级的,易使用的消息推送api
frontoldman
2019/09/02
1.5K0
服务端主动推送数据,除了 WebSocket 你还能想到啥?
松哥原创的 Spring Boot 视频教程已经杀青,感兴趣的小伙伴戳这里-->Spring Boot+Vue+微人事视频教程
江南一点雨
2021/07/15
2.8K0
服务端主动推送数据,除了 WebSocket 你还能想到啥?
PHP结合JavaScript SSE(流式显示)实现服务器实时推送功能
SSE 的全称是 Server Sent Events,即服务器推送事件。它是一种基于 HTTP 的服务器到客户端的单向(半双工)通信机制,使服务器能够主动将实时数据推送给客户端,而不需要客户端多次发起请求。 官方文档:https://developer.mozilla.org/en-US/docs/Web/API/EventSource
超级小可爱
2024/03/26
8730
.NET 如何实现ChatGPT的Stream传输
一个 EventSource 实例会对 HTTP[2] 服务器开启一个持久化的连接,以 text/event-stream 格式发送事件[3],此连接会一直保持开启直到通过调用 `EventSource.close()`[4] 关闭。
用户10786849
2023/10/13
3850
.NET 如何实现ChatGPT的Stream传输
SpringBoot仿GPT数据流传输
在折腾ChatGpt集成在SpringBoot项目时,发现了ChatGpt api返回数据时有两种返回方式,一种是使用流传输,另一种是直接返回全部的数据。如果使用流传输,响应的速度很快,不需要获取全部答案的内容后再开始响应返回,可以达到服务端返回数据时像打字机一样的效果返回答案;而直接返回全部数据的话,需要在服务端接收完ChatGpt的全部结果后再一次性把全部的数据响应返回给客户端进行展示,这个缺点就是很慢,一个结果最快也需要10秒钟。所以本文尝试模仿ChatGpt使用流数据的方式返回数据给客户端。
不愿意做鱼的小鲸鱼
2023/06/18
4.5K2
SpringBoot仿GPT数据流传输
消息推送技术,除了websocket还知道那些?
WebSocket是一种网络通信协议,它提供了在单个TCP连接上进行全双工通信的能力。这意味着数据可以在客户端和服务器之间双向流动,而无需客户端通过轮询或重复请求来获取更新。
老K博客
2024/06/01
7730
消息推送技术,除了websocket还知道那些?
精通服务器推送事件(SSE)与 Python 和 Go 实现实时数据流 🚀
在当今的互动型 Web 应用程序中,实时数据更新在提升用户体验方面起着至关重要的作用。无论是实时股票更新、即时聊天消息,还是流式评论,实时数据流都是不可或缺的。在各种可用于实时通信的技术中,服务器推送事件(SSE)作为一种广泛使用且高效的解决方案脱颖而出。SSE 允许服务器通过 HTTP 向客户端推送实时更新,提供了一种轻量且高效的方式。
用户11531559
2025/03/21
1610
传统轮询、长轮询、服务器发送事件与WebSocket
构建网络应用的过程中,我们经常需要与服务器进行持续的通讯以保持双方信息的同步。通常这种持久通讯在不刷新页面的情况下进行,消耗一定的内存资源常驻后台,并且对于用户不可见。本文将简要介绍Web通信中常用的四种方式。
kirin
2021/05/08
3.1K0
逐句回答,流式返回,ChatGPT采用的Server-sent events后端实时推送协议Python3.10实现,基于Tornado6.1
    善于观察的朋友一定会敏锐地发现ChatGPT网页端是逐句给出问题答案的,同样,ChatGPT后台Api接口请求中,如果将Stream参数设置为True后,Api接口也可以实现和ChatGPT网页端一样的流式返回,进而更快地给到前端用户反馈,同时也可以缓解连接超时的问题。
用户9127725
2023/03/13
3.4K0
逐句回答,流式返回,ChatGPT采用的Server-sent events后端实时推送协议Python3.10实现,基于Tornado6.1
【Python系列】浅析流式模式:基于 SSE 的实时响应体验
在现代 Web 应用开发中,用户体验的优化是一个非常重要的目标,尤其是在涉及到实时数据更新的场景下。流式模式(Streaming Mode)作为一种高效的数据传输方式,能够让用户以打字机输出的形式获得流式返回的效果。这种方式通过 Server-Sent Events (SSE) 技术实现,带来了独特的用户体验。
kwan的解忧杂货铺
2024/11/16
3820
SSE – Server Sent Events – 服务端主动推送
SSE是一个轻量级协议,相对简单;WebSocket是一种较重的协议,相对复杂。但SSE只支持单向交互(服务器给客户发送),Websocket支持双向交互。
收心
2022/11/22
2.8K0
SSE – Server Sent Events – 服务端主动推送
推荐阅读
相关推荐
【流式传输】使用Spring Boot实现ChatGpt流式传输
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验