日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

在Asp.net core返回PushStream

發(fā)布時間:2023/12/18 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在Asp.net core返回PushStream 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

最近用asp.net core webapi實現(xiàn)了一個實時視頻流的推送功能,在Asp.net中,這個是通過PushStreamContent來實現(xiàn)的。

基于對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調(diào)試這個接口時,發(fā)現(xiàn)它確實行之有效的將當(dāng)前的時間推送到了瀏覽器的頁面上。

然而,當(dāng)我進一步的調(diào)試它的異常情況時,發(fā)現(xiàn)就算將chrome關(guān)掉,這個程序卻依然在繼續(xù)運行。從調(diào)試器中看到stream的狀態(tài)為Aborted,已經(jīng)識別到位終止的流了。

  

并且從VS的調(diào)試窗口也能看到異常信息:

  

但下面這兩行就是不拋異常:

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

單單從接口的實現(xiàn)角度上來看,這個已經(jīng)不合理了。這是一個很大的坑,功能看上去還是正確的,沒有詳細調(diào)試還看不出來。一個不留神就踩上了。不知道微軟為什么要這么設(shè)計。

埋怨歸埋怨,問題還是要解決的。我查看了下FileStreamResult的源碼,發(fā)現(xiàn)它是靠HttpContext.RequestAborted來判斷客戶端是否終止了的。這是一個CancellationToken類型的對象,當(dāng)客戶端連接斷開后,它就處于被取消的狀態(tài)。

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

[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);} }

?

轉(zhuǎn)載于:https://www.cnblogs.com/TianFang/p/8502770.html

總結(jié)

以上是生活随笔為你收集整理的在Asp.net core返回PushStream的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。