0

我正在構建一個基於ASP.NET Core的小型Web應用程序。我的應用程序是通過服務將視頻從客戶端傳輸到客戶端。保持連接活着在ASP.NET Core中流式傳輸

我已經按照這個帖子:

http://www.strathweb.com/2013/01/asynchronously-streaming-video-with-asp-net-web-api/

我已經成功地實現教程的應用程序,但是,這是從服務器的視頻流給客戶。

我想現在要做的是:

  • 客戶端註冊爲流媒體服務。 (使用視頻或音頻標籤)
  • 服務接收客戶端提交的數據(通過郵遞員提交)
  • 服務將數據廣播到其每個註冊客戶端。

以下是我已經實現:

(Index.cshtml)

<div> 
    <video width="480" 
      height="320" 
      controls="controls" 
      autoplay="autoplay"> 
     <source  src="/api/video/initiate" 
        type="video/mp4"> 
     </source> 
    </video> 
</div> 

StreamingService

public class StreamingService: IStreamingService 
{ 
    public IList<Stream> Connections {get;set;} 

    public StreamingService() 
    { 
     Connections = new List<Stream>(); 
    } 

    public byte[] AnalyzeStream(Stream stream) 
    { 
     long originalPosititon = 0; 
     if (stream.CanSeek) 
     { 
      originalPosititon = stream.Position; 
      stream.Position = 0; 
     } 

     try 
     { 
      var readBuffer = new byte[4096]; 
      int bytesReader; 

      while ((byteRead = stream.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0) 
      { 
       totalBytesRead += byteRead; 

       if (totalBytesRead == readBuffer.Length) 
       { 
        var nextByte = stream.ReadByte(); 
        if (nextByte != -1) 
        { 
         var temp = new byte[readBuffer * 2]; 
         Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length); 
         Buffer.SetByte(temp, totalBytesRead, (byte)nextByte); 
         readBuffer = temp; 
         totalBytesRead++; 
        } 
       } 
      } 

      var buffer = readBuffer; 
      if (readBuffer.Length != totalBytesRead) 
      { 
       buffer = new byte[totalBytesRead]; 
       Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead); 
      } 

      return buffer; 
     } 
     finally 
     { 
      if (stream.CanSeek) 
       stream.Position = originalPosititon; 
     } 
    } 
} 

視頻控制器

public class VideoController: Controller 
{ 
    private readonly IStreamingService _streamingService; 

    private readonly IHostingEnvironment _hostingEnvironment; 

    public VideoController(IStreamingService streamingService, IHostingEnvironment hostingEnvironment) 
    { 
     _streamingService = streamingService; 
     _hostingEnvironment = hostingEnvironment; 
    } 

    [HttpGet("initiate")] 
    public IActionResult Initiate() 
    { 
     _streamingService.Connections.Add(Response.Body); 
    } 

    [HttpPost("broadcast")] 
    public async Task<IActionResult> Broadcast() 
    { 
     // Retrieve data submitted from POSTMAN. 
     var data = _streamingService.AnalyzeStream(Request.Body); 

     foreach (var stream in _streamingService.Connections) 
     { 
      try 
      { 
       await stream.WriteAsync(data, 0, data.Length); 
      } 
      catch (Exception exception) 
      { 
       stream.Dispose(); 
       _streamingService.Connections.Remove(stream); 
      } 
     } 
    } 
} 

當我通過api/video/broadcast發送來自POSTMAN的數據時。對於循環運行,我得到一個異常說,流已被處置。

我的問題是:

  • 我怎能流活着流?

(在API /視頻創建流/發起保持活着,當客戶端調用API /視頻/廣播,都開始流將更新它的日期,而不必設置)

謝謝

回答

0

是否可以將流保持在緩存中?

您可以閱讀更多關於它here。將緩存服務添加到依賴注入容器的最簡單方法,並通過VideoController中的構造器注入請求IMemoryCache的具體實現(正如您對IStreamingService和IHostingEnvironment所做的那樣)。

只需將流添加到緩存,並在下一次點擊api/video/broadcast時使用緩存流。

請注意,如果您在網絡農場或託管在雲中,建議您使用Distributed Cache(如Redis緩存),否則您的緩存可能會消失。例如,使用Azure Redis Cache這很好用!

+0

但是當我訪問它時丟棄了流。我可以通過使用IMemoryCache保持客戶端和服務器之間的連接嗎? – Redplane

+0

我的不好,我應該先問你一件事。如何註冊IStreamingService?哪一輩子?瞬態,範圍或Singleton? –

+0

我使用IStreamingService作爲單例(services.AddSingeton ()) – Redplane