在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

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

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

相关文章

顺序栈的代码实现

栈是一种限定只在表尾进行插入或删除操作的线性表&#xff0c;栈也是线性表。表头称为栈的底部,表尾称为栈的顶部,表为空称为空栈。 栈又称为后进先出的线性表,栈也有两种表示:顺序栈与链式栈。顺序栈是利用一组地址连续的存储单元。依次存放从栈底到栈顶的数据元素。 #includ…

Linux5观察doc目录并截屏,linux截屏命令

linux系统我们有时需要用到截屏功能&#xff0c;下面由学习啦小编为大家整理了linux截屏命令的相关知识&#xff0c;希望对大家有帮助!linux截屏命令详解import检测&#xff1a;import --versionimprot安装&#xff1a;sudo apt-get install importimport常用命令&#xff1a;1…

eclipse+tomcat开发web程序

环境&#xff1a;windows 7Eclipse Java EE IDE for Web Developerstomcat 7.02 插件&#xff1a;tomcatPluginV321.zip 一.配置Tomcat插件 我们创建一个myplugins文件夹用于存放插件&#xff0c;myplugins位于D:/Program Files/J2EE目录下。eclipse安装路径为&#xff1a;D:/P…

LoadRunner参数包含逗号

loadrunner的参数以逗号区分&#xff0c; 如果参数本身包含逗号&#xff0c;则会报错 使用","将逗号包起来即可&#xff0c;如下图 转载于:https://www.cnblogs.com/cherrysu/p/8507649.html

软件创业见闻

今天应一位朋友的邀请&#xff0c;过去蹭了个饭吃&#xff0c;顺便坐了一个下午在聊着。这位老哥是一家软件公司的老板&#xff0c;原来是从硬件销售转型到做软件这一块。因为说到软件这一块&#xff0c;我就很想了解一下这位老哥对于2009年的大势是怎么看的&#xff0c;在2009…

如何采用设置标志的方法来区分循环队列的满和空

设立一个标志位,比如说是flag 最开始时队列为空,设flag0 当入队的时候让flag1 出队的时候flag0 然后再加上判断队头队尾指针是否重合 重合,且flag0,则为空 重合且flag1,则为满

linux内核定义的常用信号6,linux复习

(3)设定apache服务器的网页根目录&#xff1a;/home/htdocs(4)在此apache服务器上设定一个目录/home/htdocs/inside,且此目录只允许IP地址为192.168.1.5的主机访问(5)定义apache服务器以独立进程的方式运行2、某系统管理员需每天做一定的重复工作&#xff0c;请按照下列要求&am…

linux 脚本 整数 赋值,shell基础!!熟悉编程规范与变量

一、SHELL规范SHELL简单介绍Bash(/bin/bash)是目前大多数 Linux 版本采用的默认 Shell。Bash 的全称为 Bourne Again Shell&#xff0c;是最受欢迎的开源软件项目之一。SHELL脚本简单的来说&#xff0c;就是将平时使用的各种 Linux 命令按顺序保存到一个文本文件中&#xff0c;…

一维数组的定义方式

一维数组的定义方式 在C语言中使用数组必须先进行定义。 一维数组的定义方式为&#xff1a;类型说明符 数组名 [常量表达式];其中&#xff0c;类型说明符是任一种基本数据类型或构造数据类型。数组名是用户定义的数组标识符。方括号中的常量表达式表示数据元素的个数&#xff…

UIButton或UILabel加个下划线

UIButton ####Objective - C LXYHyperlinksButton.h interface LXYHyperlinksButton : UIButton {UIColor *lineColor; }-(void)setColor:(UIColor*)color; 复制代码LXYHyperlinksButton.m #import "LXYHyperlinksButton.h"implementation LXYHyperlinksButton- (id)…

android studio发布项目到github

点击file setting ,打开对话框&#xff0c;如下&#xff0c;判断git是否安装成功 选择GitHub&#xff0c;填写github地址及密码 发布项目&#xff1a; 转载于:https://www.cnblogs.com/haihai88/p/8514683.html

在不使用{}时,else执行到哪里结束

正常情况下,if-else语句使用{}.执行时也执行{}里面的所有语句&#xff0c;但是当语句比较简单时&#xff0c; 可以不使用{},而直接在if或else的后面写要执行的语句。 但是程序只会执行到if或else语句后的第一个“;”其余的程序不在if-else的程序范围内。

6个变态的C语言写的Hello World

下面的六个程序片段主要完成这些事情&#xff1a; 输出Hello, World混乱C语言的源代码 下面的所有程序都可以在GCC下编译通过&#xff0c;只有最后一个需要动用C的编译器g才能编程通过。 hello1.c #define _________ }#define ________ putchar#define _______ main#define …

linux系统pcb软件下载,开源PCB设计软件KiCad致力于下一个大版本的发布

KiCad仍然是PCB设计和其他功能的领先开源电子设计套件。KiCad在2018年取得了成功&#xff0c;System76甚至使用了该软件作为与Thelio台式计算机一起设计的子板PCB的一部分&#xff0c;但展望未来&#xff0c;开发人员仍在努力开发6.0版本。KiCad 6.0发布方式将采用重新设计的GT…

CocoaPods pod install/pod update更新慢的问题

最近使用CocoaPods来添加第三方类库&#xff0c;无论是执行pod install还是pod update都卡在了Analyzing dependencies不动原因在于当执行以上两个命令的时候会升级CocoaPods的spec仓库&#xff0c;加一个参数可以省略这一步&#xff0c;然后速度就会提升不少。加参数的命令如下…

js call(),apply(),对象冒充,改变变量作用域

1.apply(); function box(n1,n2){return n1n2; } function pox(n1,n2){alert(box.apply(this,[n1,n2])); //this指window下全局属性//这里没有返回值,没有运算,通过冒充box里的运算来执行 } pox(10,20); //30 注:如果参数过多,冒充对象传参的时候可以写成arguments fu…

数组元素的地址计算问题(一维到高维)

数组元素存储地址的计算 一维数组 设一维数组A[n]存放在n个连续的存储单元中&#xff0c;每个数组元素占一个存储单元&#xff08;不妨设为C个连续字节&#xff09;.如果数组元素A[0]的首地址是L&#xff0c;则A[1]的首地址是LC&#xff0c;A[2]的首地址是L2C&#xff0c;… …

侯宁:不该捞的别去捞 踏空不是浪费时间

最近&#xff0c;偶然间在网上看到了一则寓言故事&#xff1a;《骆驼与北斗星》。文章不长&#xff0c;但内容丰富&#xff0c;讲得很有趣&#xff0c;很有哲理&#xff0c;也很有启发。尤其是在股市博弈中&#xff0c;许多人、许多机构都会在现实中扮演故事里的不同角色。因为…

大跃进和循序渐进

大跃进和循序渐进本身没有对错&#xff0c;只有跟具体情境结合起来才会产生对错属性。 好的大跃进就是不学走先学跑&#xff0c;deadline是第一生产力&#xff0c;一旦学会了更高级的&#xff0c;低级的自然而然就学会了。 好比武装革命&#xff0c;是先攻打大城市还是攻打农村…

Hibernate 学习(一)

一、Hibernate 简介 1、Hibernate 简介 Hibernate是一个开放源代码的对象关系映射(ORM)框架&#xff0c;它对JDBC进行了非常轻量级的对象封装&#xff0c;它将POJO与数据库表建立映射关系&#xff0c;是一个全自动的orm框架&#xff0c;hibernate可以自动生成SQL语句&#xff0…