欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Asp.net core實現(xiàn)PushStream視頻流推送

 更新時間:2022年07月01日 09:49:25   作者:天方  
這篇文章介紹了Asp.net core實現(xiàn)PushStream視頻流推送的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

最近用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 + @"
";
        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)我進(jìn)一步的調(diào)試它的異常情況時,發(fā)現(xiàn)就算將chrome關(guān)掉,這個程序卻依然在繼續(xù)運(yùn)行。從調(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)不合理了。這是一個很大的坑,功能看上去還是正確的,沒有詳細(xì)調(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 + @"
";
        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);
    }
}

到此這篇關(guān)于Asp.net core返回PushStream的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論