0

私はASP.NETコアで構築された小さなWebアプリケーションを作っています。私のアプリケーションは、サービスからクライアントへのビデオストリーミング用です。ASP.NETコアでストリーミング接続を維持する

私はこの記事を踏襲してきました:

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

私は、サーバからクライアントにビデオをストリーミングするためだったこと、成功したチュートリアルのアプリケーションを実装しますが、しました。私が今したい何

は次のとおりです。

  • クライアントは、ストリーミングのためにサービスを提供するために登録します。
  • サービスはクライアントから送信されたデータを受信します(POSTMAN経由で送信)
  • サービスは登録されたすべてのクライアントにデータをブロードキャストします。ここで

は、私が実装したものです:

(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; 
     } 
    } 
} 

のVideoController

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

私はPOSTMANからのデータをapi/video/broadcast経由で送信します。ループが実行され、例外が発生しました。ストリームが破棄されました。

私の質問は:

  • は、どのように私はストリーミングのための生きている流れを保つことができますか?

(API /ビデオ/に作成されたストリーム開始が生き続けていると、クライアントは、API /ビデオ/ブロードキャストを呼び出したときに、すべての開始ストリームを配置せずにその日付を更新します)

は、

をありがとう

答えて

0

ストリームをキャッシュに保存するオプションはありますか?

詳しくはhereをご覧ください。キャッシュサービスを依存関係注入コンテナに追加する最も簡単な方法と、VideoControllerのコンストラクタインジェクションを使用してIMemoryCacheの具体的な実装をリクエストします(IStreamingServiceおよびIHostingEnvironmentで行ったように)。

ストリームをキャッシュに追加し、次回にapi/video/broadcastにヒットしたときにキャッシュされたストリームを使用するだけです。

Webファームやクラウドでホストされている場合は、Redis CacheのようにDistributed Cacheを使用することをお勧めします。そうしないと、キャッシュが予期せず消えてしまう可能性があります。私はAzure Redis Cacheを使用しています。

+0

ただし、ストリームにアクセスするとストリームが破棄されます。 IMemoryCacheを使用してクライアントとサーバー間の接続を維持できますか? – Redplane

+0

私の悪い、私はあなたに何か最初に尋ねてきたはずです。どのようにIStreamingServiceを登録しなければなりませんか?どの生涯?トランジェント、スコープ、またはシングルトン? –

+0

シングルトンとしてIStreamingServiceを使用します(services.AddSingeton ())。 – Redplane

関連する問題