¿Cómo encajan los recursos de streaming dentro del paradigma RESTful?


Con un servicio RESTful puede crear, leer, actualizar y eliminar recursos. Todo esto funciona bien cuando se trata de algo como activos de una base de datos, pero ¿cómo se traduce esto en datos de transmisión? (¿ O lo hace?) Por ejemplo, en el caso del video, parece tonto tratar cada fotograma como un recurso que debería consultar uno a la vez. Más bien establecería una conexión de socket y transmitiría una serie de marcos. ¿Pero esto rompe el paradigma de descanso? ¿Qué pasa si quiero ser capaz de rebobinar ¿o adelantar la corriente? ¿Es esto posible dentro del paradigma de descanso? Entonces: ¿Cómo encajan los recursos de streaming dentro del paradigma RESTful?

Como cuestión de implementación, me estoy preparando para crear un servicio de transmisión de datos de este tipo, y quiero asegurarme de que lo estoy haciendo de la "mejor manera". Estoy seguro de que este problema ha sido resuelto antes. ¿Alguien puede indicarme un buen material?

Author: Tim Cooper, 2011-01-28

1 answers

No logré encontrar materiales sobre truly RESTful streaming - parece que los resultados son principalmente sobre la delegación de streaming a otro servicio (que no es una mala solución). Así que voy a hacer mi mejor esfuerzo para abordarlo yo mismo - tenga en cuenta que la transmisión no es mi dominio, pero voy a tratar de añadir mis 2 centavos.

En el aspecto de la transmisión, creo que necesitamos separar el problema en dos partes independientes:

  1. acceso a recursos multimedia (metadatos)
  2. acceso a el medio / flujo en sí (datos binarios)

1.) Acceso a recursos multimedia
Esto es bastante sencillo y se puede manejar de una manera limpia y tranquila. Como ejemplo, digamos que tendremos una API basada en XML que nos permite acceder a una lista de flujos:

GET /media/

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

...y también a las corrientes individuales:

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.) Acceso al medio/corriente en sí
Esta es la parte más problemática. Usted ya señaló una opción en su pregunta, y que es permitir el acceso a los marcos individualmente a través de una API RESTful. Aunque esto podría funcionar, estoy de acuerdo contigo en que no es una opción viable.

Creo que hay que elegir entre:{[11]]}

  1. delegar la transmisión a un servicio dedicado a través de un protocolo de transmisión especializado (por ejemplo, RTSP)
  2. utilizando opciones disponibles en HTTP

Creo que la primera es la opción más eficiente, aunque requiere un dedicado servicio de streaming (y / o hardware). Podría estar un poco al borde de lo que se considera RESTful, sin embargo, tenga en cuenta que nuestra API es RESTful en todos los aspectos y aunque el servicio de transmisión dedicado no se adhiere a la interfaz uniforme (GET/POST/PUT/DELETE), nuestra API sí. Nuestra API nos permite un control adecuado sobre los recursos y sus metadatos a través de GET/POST/PUT/DELETE, y proporcionamos enlaces al servicio de streaming (adhiriéndose así con el aspecto de conectividad de REST).

Este último opción - streaming vía HTTP - podría no ser tan eficiente como el anterior, pero es definitivamente posible. Técnicamente, no es tan diferente de permitir el acceso a cualquier forma de contenido binario a través de HTTP. En este caso, nuestra API proporcionaría un enlace al recurso binario accesible a través de HTTP, y también nos aconseja sobre el tamaño del recurso:

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>

El cliente puede acceder al recurso vía HTTP usando GET /media/1.3gp. Una opción es que el cliente descargue todo el recurso - Descarga progresiva HTTP . Una alternativa más limpia sería que el cliente accediera al recurso en trozos utilizando encabezados de rango HTTP . Para obtener el segundo fragmento de 256KB de un archivo de 1 MB de tamaño, la solicitud del cliente se vería así:

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

Un servidor que soporta rangos respondería con el encabezado Content-Range , seguido de la representación parcial del recurso:

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

Tenga en cuenta que nuestra API ya le dijo a la cliente el tamaño exacto del archivo en bytes (1MB). En caso de que el cliente no conozca el tamaño del recurso, primero debe llamar a HEAD /media/1.3gp para determinar el tamaño, de lo contrario se arriesga a una respuesta del servidor con 416 Requested Range Not Satisfiable.

 71
Author: MicE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-28 21:12:18