Asp.net core实现PushStream视频流推送

最近用asp.net core webapi实现了一个实时视频流的推送功能,在Asp.net中,这个是通过PushStreamContent来实现的。

基于对asp.net core的知识,随手写了一个(要求控制器继承自Controller基类)

[HttpGet]
public async Task Get()
{
    var response = HttpContext.Response;
    response.ContentType = "text/html";
    response.StatusCode = 200;
    var stream = HttpContext.Response.Body;

    while (true)
    {
        await Task.Delay(1000);
        var content = DateTime.Now + @"
";
        var data = Encoding.Default.GetBytes(content);
        await stream.WriteAsync(data, 0, data.Length);
        await stream.FlushAsync();
    }
}

使用chrome调试这个接口时,发现它确实行之有效的将当前的时间推送到了浏览器的页面上。

然而,当我进一步的调试它的异常情况时,发现就算将chrome关掉,这个程序却依然在继续运行。从调试器中看到stream的状态为Aborted,已经识别到位终止的流了。

并且从VS的调试窗口也能看到异常信息:

但下面这两行就是不抛异常:

await stream.WriteAsync(data, 0, data.Length);
await stream.FlushAsync();

单单从接口的实现角度上来看,这个已经不合理了。这是一个很大的坑,功能看上去还是正确的,没有详细调试还看不出来。一个不留神就踩上了。不知道微软为什么要这么设计。

埋怨归埋怨,问题还是要解决的。我查看了下FileStreamResult的源码,发现它是靠HttpContext.RequestAborted来判断客户端是否终止了的。这是一个CancellationToken类型的对象,当客户端连接断开后,它就处于被取消的状态。

知道原因后,就可以知道如何修改我的程序了。

[HttpGet]
public async Task Get()
{
    var cancel = HttpContext.RequestAborted;

    var response = HttpContext.Response;
    response.ContentType = "text/html";
    response.StatusCode = 200;
    var stream = HttpContext.Response.Body;

    while (true)
    {
        cancel.ThrowIfCancellationRequested();
        await Task.Delay(1000, cancel);
        var content = DateTime.Now + @"
";
        var data = Encoding.Default.GetBytes(content);
        await stream.WriteAsync(data, 0, data.Length, cancel);
        await stream.FlushAsync(cancel);
    }
}

再然后就是封装了,我这里将其封装为了一个PushStreamResult,这样就可以在PocoController中使用了。

class MyPushStreamResult :IActionResult
{
    Func<Stream, CancellationToken, Task> _pushAction;
    string _contentType;

    public MyPushStreamResult(Func<Stream, CancellationToken, Task> pushAction, string contentType)
    {
        _pushAction = pushAction;
        _contentType = contentType;
    }

    public Task ExecuteResultAsync(ActionContext context)
    {
        var response = context.HttpContext.Response;
        response.ContentType = _contentType;
        response.StatusCode = 200;

        return _pushAction(response.Body, context.HttpContext.RequestAborted);
    }
}

使用方法如下:

[HttpGet]
public IActionResult Get()
{
    return new MyPushStreamResult(pushData, "text/html");
}

async Task pushData(Stream stream, CancellationToken cancel)
{
    while (true)
    {
        if (cancel.IsCancellationRequested)
            return;
        await Task.Delay(1000, cancel);
        var content = DateTime.Now + @"<br>";
        var data = Encoding.Default.GetBytes(content);
        await stream.WriteAsync(data, 0, data.Length, cancel);
        await stream.FlushAsync(cancel);
    }
}

到此这篇关于Asp.net core返回PushStream的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • .Net Core限流的实现示例

    目录 一.环境 二.基础使用 1.设置 2.规则设置 3.特殊规则的启用 三.请求返回头 四.使用Redis存储 1.访问计数 2.ip特殊规则 3.客户端特殊规则 五.修改规则 一.环境 1.vs2019 2..Net Core 3.1 3.引用 AspNetCoreRateLimit 4.0.1 二.基础使用 1.设置 在Startup文件中配置如下,把配置项都放在前面: public void ConfigureServices(IServiceCollection services) {

  • ASP.NET Core中间件实现限流的代码

    目录 一.限流算法 1.计数器算法 1.1固定窗口算法 1.2滑动窗口算法 2.令牌桶算法 3.漏桶算法 二.ASP.NETCore中间件实现限流 1.中间件代码 2.在管道中的使用 一.限流算法 在高并发系统中,有三把利器用来保护系统:缓存.降级和限流. 本文主要是介绍限流,限流算法主要有以下三种: 1.计数器算法 固定窗口 滑动窗口 2.令牌桶算法 3.漏桶算法 1.计数器算法 1.1 固定窗口算法 计数器算法是限流算法里最简单也是最容易实现的一种算法.比如我们规定,对于A接口来说,我们1分

  • Asp.NET Core 限流控制(AspNetCoreRateLimit)的实现

    起因: 近期项目中,提供了一些调用频率较高的api接口,需要保障服务器的稳定运行:需要对提供的接口进行限流控制.避免因客户端频繁的请求导致服务器的压力. 一.AspNetCoreRateLimit 介绍 AspNetCoreRateLimit 是一个ASP.NET Core速率限制的解决方案,旨在控制客户端根据IP地址或客户端ID向Web API或MVC应用发出的请求的速率.AspNetCoreRateLimit包含一个 IpRateLimitMiddleware 和 ClientRateLim

  • ASP.NET Core SignalR中的流式传输深入讲解

    前言 什么是流式传输? 流式传输是这一种以稳定持续流的形式传输数据的技术. 流式传输的使用场景 有些场景中,服务器返回的数据量较大,等待时间较长,客户端不得不等待服务器返回所有数据后,再进行相应的操作.这时候使用流式传输,可以将服务器数据碎片化,当每个数据碎片读取完成之后,就只传输完成的部分,而不需要等待所有数据都读取完成. SignalR SignalR是一个.NET Core/.NET Framework的开源实时框架. SignalR的可使用Web Socket, Server Sent

  • ASP.NET Core基于滑动窗口实现限流控制

    目录 前言: 二.固定窗口算法 三.滑动窗口算法 四.实现 六.使用 结论: 前言: 在实际项目中,为了保障服务器的稳定运行,需要对接口的可访问频次进行限流控制,避免因客户端频繁请求导致服务器压力过大. 而​AspNetCoreRateLimit是目前ASP.NET Core下最常用的限流解决方案. 查看它的实现代码,我发现它使用的固定窗口算法. var entry = await _counterStore.GetAsync(counterId, cancellationToken); if

  • ASP.NET Core使用固定窗口限流

    目录 算法原理 算法实现 进程内即内存固定窗口算法 基于Redis的固定窗口算法 算法应用 1.安装Nuget包 2.使用中间件 算法原理 固定窗口算法又称计数器算法,是一种简单的限流算法.在单位时间内设定一个阈值和一个计数值,每收到一个请求则计数值加一,如果计数值超过阈值则触发限流,如果达不到则请求正常处理,进入下一个单位时间后,计数值清零,重新累计. 如上图所示,时间单位是1秒,阈值是3. 第1秒3个请求,不会触发限流: 第2秒1个请求,不会触发限流: 第3秒4个请求,这一秒的前3个请求正常

  • ASP.NET Core对不同类型的用户进行区别限流详解

    前言 老板提出了一个新需求,从某某天起,免费用户每天只能查询100次,收费用户100W次. 这是一个限流问题,聪明的你也一定想到了如何去做:记录用户每一天的查询次数,然后根据当前用户的类型使用不同的数字做比较,超过指定的数字就返回错误. 嗯,原理就是这么简单.不过真正写起来还要考虑更多问题: 统计数据的数据结构是什么样的?字典 or 行记录? 统计数据记录到哪里?内存 or MySQL or Redis? 分布式应用怎么精确计数?分布式锁 or 队列 or 事务? 吞吐量比较大时如何扛得住?内存

  • Asp.net core实现PushStream视频流推送

    最近用asp.net core webapi实现了一个实时视频流的推送功能,在Asp.net中,这个是通过PushStreamContent来实现的. 基于对asp.net core的知识,随手写了一个(要求控制器继承自Controller基类) [HttpGet] public async Task Get() { var response = HttpContext.Response; response.ContentType = "text/html"; response.Sta

  • .NET对接极光消息推送的实现方法

    目录 什么是APP消息推送? 极光推送介绍 快速对接Jpush极光推送 .NET FX 4.5项目接入 相关链接地址 什么是APP消息推送? 很多手机APP会不定时的给用户推送消息,例如一些新闻APP会给用户推送用户可能感兴趣的新闻,或者APP有更新了,会给用户推送是否选择更新的消息等等,这就是所谓的“消息推送”. 更多APP消息推送的介绍可查阅该篇文章:十分钟带你了解APP消息推送(Push) 如下是我们日常生活中常见的一些APP消息推送示例: 强营销类: 直接把营销力度,营销模式以一种叫卖式

  • Asp.net core 使用SignalR推送消息过程详解

    1).SignalR简介 ASP.NET Core SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程. 实时 Web 功能是指这样一种功能:当所连接的客户端变得可用时服务器代码可以立即向其推送内容,而不是让服务器等待客户端请求新的数据. 2).SignalR主要用途: 它出现的主要用途:可以用在聊天室.Web实时推送消息 (Real-Push-Message).单点和多点通讯.扫码登陆.甚至可以结合其他技术用来做视频聊天等等.

  • ASP.NET SignaiR 实现消息的即时推送,并使用Push.js实现通知的示例代码

    一.使用背景 1. SignalR是什么? ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程.实时 Web 功能是指这样一种功能:当所连接的客户端变得可用时服务器代码可以立即向其推送内容,而不是让服务器等待客户端请求新的数据. 2.Push.js是什么?[需要浏览器支持H5Notifications] Notifications翻译过来即是通知.那么Push.js的通知又是什么样的,见下图:大多数在屏幕的右下角出

  • Asp.NET MVC中使用SignalR实现推送功能

    一.简介 Signal 是微软支持的一个运行在 Dot NET 平台上的 html websocket 框架.它出现的主要目的是实现服务器主动推送(Push)消息到客户端页面,这样客户端就不必重新发送请求或使用轮询技术来获取消息. 可访问其官方网站:https://github.com/SignalR/ 获取更多资讯. 二.Asp.net SignalR 是个什么东东 Asp.net SignalR是微软为实现实时通信的一个类库.一般情况下,SignalR会使用JavaScript的长轮询(lo

  • ASP.NET实现推送文件到浏览器的方法

    本文实例讲述了ASP.NET实现推送文件到浏览器的方法.分享给大家供大家参考.具体分析如下: 这里主要实现从服务器到浏览器,推送文件,提供用户下载/浏览的功能. 提示: 在AJAX UpdatePanel里面将无效.如果代码从按钮单击事件中被调用,该按钮需要在 AJAX UpdatePanel的外部. 具体代码如下: /// <summary> /// Downloads (pushes) file to the client browser. /// **** NOTE **** Canno

  • asp.net mvc实现简单的实时消息推送

    因为项目需要,需要在网页上实现消息的推送.在百度上搜索了一下,发现实现网页上的消息推送,可以使用asp.net 中的SignalR类库,当然也可以使用H5的WebSocket  Ajax的轮回.当然此处我们使用asp.net 中的SignalR类库.因为它可以实现网页上消息的实时推送.什么是实时推送呢,我简单的说一下我个人的理解吧.实时:在同一时间类发生的事情,当然在计算机中并不是绝对的实时,因为CPU在同一时间片只能处理一个任务,那么这个时候疑问又来了? 我们平时使用电脑又上网,又听音乐是如何

  • ASP 百度主动推送代码范例

    范例代码 function BytesToBstr(body,Cset)     dim objstream  set objstream = Server.CreateObject("adodb.stream") objstream.Type = 1  objstream.Mode =3  objstream.Open  objstream.Write body  objstream.Position = 0  objstream.Type = 2  objstream.Charse

  • ASP.net百度主动推送功能实现代码

    官方提供了curl.post.php.ruby的实现示例,并没有C#的官方示例.既然提供了post的方式,那么就可以用C#实现,下面是实现代码: ASP.net百度主动推送代码范例 public static string PostUrl(string[] urls)      {          try         {              string formUrl = "http://data.zz.baidu.com/urls?site=www.yoursite.com&am

  • .NET Core实现企业微信消息推送

    接口定义 应用支持推送文本.图片.视频.文件.图文等类型.请求方式:POST(HTTPS)请求地址: https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=ACCESS_TOKEN 参数说明: ACCESS_TOKEN 必填 - 各个消息类型的具体POST格式请阅后续“消息类型”部分.- 如果有在管理端对应用设置“在微工作台中始终进入主页”,应用在微信端只能接收到文本消息,并且文本消息的长度限制为20字节,超过20字节会被截断

随机推荐