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的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
相关文章
在 Net7.0 环境下如何使用 RestSharp 发送 Http(FromBody和FromForm)请求
这篇文章主要介绍了在 Net7.0 环境下使用 RestSharp 发送 Http(FromBody和FromForm)请求,今天,我就两个小的知识点,就是通过使用 RestSharp 访问 WebAPI,提交 FromBody 和 FromForm 两种方式的数据,还是有些区别的,本文结合实例代码介绍的非常详细,需要的朋友参考下吧2023-09-09EFCore 通过实体Model生成创建SQL Server数据库表脚本
这篇文章主要介绍了EFCore 通过实体Model生成创建SQL Server数据库表脚本的示例,帮助大家更好的理解和学习使用.net框架,感兴趣的朋友可以了解下2021-03-03asp.net下使用DbProviderFactories的数据库操作类
项目开发中用到VB.NET开发,参考网上的资料,自己写了数据库操作类。2010-06-06visual studio 2019使用net core3.0创建winform无法使用窗体设计器
这篇文章主要介绍了visual studio 2019使用net core3.0创建winform无法使用窗体设计器,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2020-03-03
最新评论