0

Ich mache eine kleine Web-Anwendung, die auf ASP.NET Core gebaut wird. Meine Anwendung dient zum Streaming von Videos von Clients zu Clients über den Dienst.Keep Verbindung lebendig für Streaming in ASP.NET Core

Ich habe diesen Beitrag gefolgt:

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

ich die Anwendung von Tutorial erfolgreich umgesetzt haben, aber, dass Video vom Server an den Kunden für das Streaming war.

Was ich jetzt tun möchte, ist:

  • Clients registrieren für Streaming-Service. (mit Video-oder Audio-Tag)
  • Service empfängt Client übermittelt Daten (über POSTMAN senden)
  • Service Broadcast die Daten zu jedem registrierten Clients.

Hier ist, was ich implementiert haben:

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

Wenn ich Daten von POSTMAN über API/Video/Broadcast senden. For-Schleife lief und ich habe eine Ausnahme, sagte der Strom wurde entsorgt.

Meine Frage ist:

  • Wie kann ich den Strom für das Streaming am Leben zu erhalten?

(Strom erzeugt in api/Video/initiate wird am Leben gehalten und, wenn ein Client api/Video/Broadcast-Anrufe, die alle eingeleiteten Strom wird das Datum aktualisieren, ohne entsorgt zu haben)

Danke,

Antwort

0

Ist es eine Option, den Stream im Cache zu behalten?

Sie können mehr darüber lesen here. Die einfachste Möglichkeit, die Cache-Dienste dem Dependency-Injection-Container hinzuzufügen und die konkrete Implementierung von IMemoryCache durch Konstruktorinjektion in Ihrem VideoController anzufordern (wie Sie es mit IStreamingService und IHostingEnvironment getan haben).

Fügen Sie einfach den Stream zum Cache hinzu und verwenden Sie den zwischengespeicherten Stream, wenn Sie das nächste Mal auf api/video/broadcast tippen.

Beachten Sie jedoch, dass wenn Sie auf einer Webfarm sind oder in der Cloud gehostet werden, es empfohlen wird, Distributed Cache wie Redis Cache zu verwenden, sonst könnte Ihr Cache unerwartet verschwinden. Ich benutze zum Beispiel Azure Redis Cache, das funktioniert super!

+0

Aber Strom wird entsorgt, wenn ich darauf zugreife. Kann ich die Verbindung zwischen Client und Server mithilfe von IMemoryCache beibehalten? – Redplane

+0

Mein schlechtes, ich hätte dich zuerst etwas fragen sollen. Wie muss ich IStreamingService registriert haben? Welche Lebenszeit? Transient, Scope oder Singleton? –

+0

Ich benutze IStreamingService als Singleton (services.AddSingeon ()) – Redplane