In che modo le risorse di streaming si adattano al paradigma RESTful?


101

Con un servizio RESTful puoi creare, leggere, aggiornare ed eliminare risorse. Funziona tutto bene quando hai a che fare con qualcosa come le risorse di un database, ma come si traduce in dati in streaming? (O lo fa?) Ad esempio, nel caso del video, sembra sciocco trattare ogni frame come una risorsa che dovrei interrogare uno alla volta. Piuttosto vorrei impostare una connessione socket e trasmettere in streaming una serie di frame. Ma questo rompe il paradigma RESTful? E se voglio essere in grado di riavvolgere o far avanzare velocemente lo stream? È possibile all'interno del paradigma RESTful? Quindi: come si adattano le risorse di streaming al paradigma RESTful?

Per quanto riguarda l'implementazione, mi sto preparando a creare un tale servizio di dati in streaming e voglio assicurarmi di farlo nel "modo migliore". Sono sicuro che questo problema sia già stato risolto. Qualcuno può indicarmi un buon materiale?


2
Quale opzione hai finalmente scelto? Hai guardato gRPc? Supporta lo streaming bidirezionale.
Mac

Risposte:


80

Non sono riuscito a trovare materiale sullo streaming veramente RESTful - sembra che i risultati riguardino principalmente la delega dello streaming a un altro servizio (che non è una cattiva soluzione). Quindi farò del mio meglio per affrontarlo da solo - nota che lo streaming non è il mio dominio, ma cercherò di aggiungere i miei 2 centesimi.

Nell'aspetto dello streaming, penso che dobbiamo separare il problema in due parti indipendenti:

  1. accesso alle risorse multimediali (metadati)
  2. accesso al mezzo / flusso stesso (dati binari)

1.) Accesso alle risorse multimediali
Questo è abbastanza semplice e può essere gestito in modo pulito e RESTful. Ad esempio, diciamo che avremo un'API basata su XML che ci consente di accedere a un elenco di flussi:

GET /media/

<?xml version="1.0" encoding="UTF-8" ?>
<media-list uri="/media">
    <media uri="/media/1" />
    <media uri="/media/2" />
    ...
</media-list>

... e anche ai singoli flussi:

GET /media/1

<?xml version="1.0" encoding="UTF-8" ?>
<media uri="/media/1">
    <id>1</id>
    <title>Some video</title>
    <stream>rtsp://example.com/media/1.3gp</stream>
</media>

2.) Accesso al mezzo / flusso stesso
Questo è il bit più problematico. Hai già indicato un'opzione nella tua domanda, ovvero consentire l'accesso ai frame individualmente tramite un'API RESTful. Anche se potrebbe funzionare, sono d'accordo con te che non è un'opzione praticabile.

Penso che ci sia una scelta da fare tra:

  1. delegare lo streaming a un servizio dedicato tramite un protocollo di streaming specializzato (es. RTSP)
  2. utilizzando le opzioni disponibili in HTTP

Credo che la prima sia la scelta più efficiente, sebbene richieda un servizio di streaming dedicato (e / o hardware). Potrebbe essere un po 'al limite di ciò che è considerato RESTful, tuttavia nota che la nostra API è RESTful in tutti gli aspetti e anche se il servizio di streaming dedicato non aderisce all'interfaccia uniforme (GET / POST / PUT / DELETE), la nostra API lo fa. La nostra API ci consente un controllo adeguato sulle risorse e sui loro metadati tramite GET / POST / PUT / DELETE e forniamo collegamenti al servizio di streaming (aderendo così all'aspetto di connessione di REST).

L'ultima opzione, lo streaming tramite HTTP , potrebbe non essere efficiente come quella precedente, ma è sicuramente possibile. Tecnicamente, non è così diverso dal consentire l'accesso a qualsiasi forma di contenuto binario tramite HTTP. In questo caso la nostra API fornirebbe un collegamento alla risorsa binaria accessibile tramite HTTP e ci informa anche sulla dimensione della risorsa:

GET /media/1

<?xml version="1.0" encoding="UTF-8" ?>
<media uri="/media/1">
    <id>1</id>
    <title>Some video</title>
    <bytes>1048576</bytes>
    <stream>/media/1.3gp</stream>
</media>

Il client può accedere alla risorsa tramite HTTP utilizzando GET /media/1.3gp. Un'opzione è che il client scarichi l'intera risorsa: il download progressivo HTTP . Un'alternativa più pulita sarebbe che il client acceda alla risorsa in blocchi utilizzando le intestazioni di intervallo HTTP . Per recuperare il secondo blocco di 256 KB di un file di 1 MB di dimensione, la richiesta del client sarà quindi simile a questa:

GET /media/1.3gp
...
Range: bytes=131072-262143
...

Un server che supporta gli intervalli risponderebbe quindi con l' intestazione Content-Range , seguita dalla rappresentazione parziale della risorsa:

HTTP/1.1 206 Partial content
...
Content-Range: bytes 131072-262143/1048576
Content-Length: 1048576
...

Nota che la nostra API ha già comunicato al cliente la dimensione esatta del file in byte (1 MB). Nel caso in cui il client non conoscesse la dimensione della risorsa, dovrebbe prima chiamare HEAD /media/1.3gpper determinare la dimensione, altrimenti rischia una risposta del server con 416 Requested Range Not Satisfiable.


2
Wow ... questa è un'ottima informazione. Hai attirato la mia attenzione su un paio di nuovi modi di pensare a questo. Inoltre non ero a conoscenza del protocollo di streaming in tempo reale.
JnBrymn

1
Nessun problema, sono contento di aver potuto aiutare. Si prega di notare, tuttavia, che non ho ancora avuto la possibilità di lavorare personalmente con i protocolli di streaming (ad eccezione dello streaming progressivo tramite HTTP). Ho scelto RTSP solo come esempio, non posso dire se potrebbe essere utile nel tuo scenario specifico. Potresti voler fare un'altra domanda SO sui protocolli di streaming in particolare. Wikipedia offre anche un buon punto di partenza per altri protocolli - vedere le sezioni "Problemi di protocollo" e "Vedere anche" qui: en.wikipedia.org/wiki/Streaming_Media
MicE

1
Grazie questa è di gran lunga la spiegazione più semplice e tecnica.
silentsudo
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.