在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 + @"<br>";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 + @"<br>";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);} }
转载于:https://www.cnblogs.com/TianFang/p/8502770.html
在Asp.net core返回PushStream相关推荐
- iactionresult 图片_从显式类型的ASP.NET Core API控制器(不是IActionResult)返回404
在ASP.NET Core 2.1中使用return null;解决了此问题: public ActionResult Get(int id) { Thing thing = GetThingFrom ...
- asp.net core系列 38 WebAPI 返回类型与响应格式--必备
一.返回类型 ASP.NET Core 提供以下 Web API Action方法返回类型选项,以及说明每种返回类型的最佳适用情况: (1) 固定类型 (2) IActionResult (3) Ac ...
- ASP.NET Core 2.2 基础知识(十四) WebAPI Action返回类型(未完待续)
要啥自行车,直接看手表 //返回基元类型public string Get(){return "hello world";} //返回复杂类型public Person Get() ...
- 客户要求ASP.NET Core API返回特定格式,怎么办?(续2)
前言 前2次,我们都是假设客户需要返回不同的字符串格式. 但是,有可能客户要求的返回是非本文格式,比如文件流. 怎么办? 思路 前提,当然还是使用同一API接口,不影响现有使用方式. 虽然ASP.NE ...
- 客户要求ASP.NET Core API返回特定格式,怎么办?(续)
前言 上次,我们用 客户就要求API的返回值属性名必须是PascalCase(如UserName),但是这些API需要同时提供给内部系统使用,默认都是CamelCase(如userName). 其实, ...
- ASP.Net Core Web API 如何返回 File。
咨询区 Jan Kruse: 我想在 ASP.Net Web API 中返回 File 文件,我目前的做法是将 Action 返回值设为 HttpResponseMessage,参考代码如下: pub ...
- 客户要求ASP.NET Core API返回特定格式,怎么办?
当ASP.NET Core API提供给到外部系统使用时,在某些情况下,可能需要根据这些外部系统的要求来格式化数据. 比如,客户就要求API的返回值属性名必须是PascalCase(如UserName ...
- asp.net core 使用newtonsoft完美序列化WebApi返回的ValueTuple
由于开发功能的需要,又懒得新建太多的class,所以ValueTuple是个比较好的偷懒方法,但是,由于WebApi需要返回序列化后的json,默认的序列化只能将ValueTuple定义的各个属性序列 ...
- ASP.NET Core WebAPI控制器返回类型的最佳选项
ASP.NET Core WebAPI控制器返回类型的最佳选项 原文:ASP.NET Core WebAPI控制器返回类型的最佳选项 前言 从.NET Core 2.1版开始,到目前为止,控制器操作可 ...
最新文章
- [BTS2004]一步一步学习BizTalk2004 CBR(content-based routing)
- 这块DIY墨水屏手表火了!外观可盐可甜,无线蓝牙计步闹钟一应俱全 | 开源
- 那些计算机界的伟大女性
- 肖婧医生直播讲稿整理
- docker中centos遇到sudo: command not found
- 分享一套基于SpringBoot和Vue的企业级中后台开源项目,代码很规范!
- 【笑话】骂人的最高境界
- Arduino IDE和ArduBlock 的下载安装
- 【转载】SQL Server 2008 中新建用户登录并指定该用户的数据库
- Java 工程师修炼之道
- 用户手册 (V4.0 版)
- 如何解决您的虚拟主机中有文件触发了安全防护报警规则,可能存在webshell网页木马...
- Linux Centos7 测试硬盘IO速度
- 你为什么要进入IT行业呢?
- Source Insight 4.0.0086 Patched
- 英语发音规则---F字母
- Traffic Flow Prediction Using Graph Convolution Neural NetworksOC 翻译笔记
- 基于51单片机俄罗斯方块游戏电路设计
- 联想g40改Android,求大神帮忙,联想g40如何改win7系统?
- python从入门到入土表情包-Python自动生成表情包,python在手,从此斗图无敌手
热门文章
- *【牛客 - 326B】背单词(线性dp)
- *【UVA - 10382】Watering Grass(贪心,区间覆盖问题,思维)
- java 与 xml_xml与java对象转换
- python 0o_Python 中的比较:is 与 ==
- nodejs 监控linux,linuxServerMonitoring
- burpsuite csrf攻击_WEB安全之CSRF
- c语言函数大全语法下载,C语言函数大全(语法).doc
- app中使用用户名/邮箱/手机号登录的思路分析
- redis——缓存击穿/穿透/雪崩
- mysql数据库表的导入导出