2011-01-28 17 views
81

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

Como una cuestión de implementación, me estoy preparando para crear dicho servicio de transmisión de datos, y quiero asegurarme de hacerlo de la "mejor manera". Estoy seguro de que este problema ha sido resuelto antes. ¿Puede alguien señalarme un buen material?

Respuesta

67

No logré encontrar materiales sobre realmente RESTful streaming - parece que los resultados son principalmente sobre la delegación de transmisión a otro servicio (lo cual no es una mala solución). Por lo tanto, haré todo lo posible para abordarlo por mi cuenta, tenga en cuenta que la transmisión no es mi dominio, pero intentaré agregar mis 2 centavos.

En el aspecto de streaming, creo que tenemos que separar el problema en dos partes independientes:

  1. acceso a los recursos multimedia (metadatos)
  2. acceso al medio/arroyo en sí (binario datos)

1.) el acceso a los recursos de los medios
Esto es muy sencillo y puede ser manejado de una manera limpia y relajante. A modo de ejemplo, digamos que vamos a tener una API basada en XML, que nos permite acceder a una lista de secuencias:

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 para 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/secuencia en sí
Este es el bit más problemático. Ya ha señalado una opción en su pregunta, y eso es para permitir el acceso a los marcos de forma individual a través de una API RESTful. Aunque esto podría funcionar, estoy de acuerdo con usted en que no es una opción viable.

Creo que hay una elección que debe hacerse entre:

  1. delegar el streaming a un servicio dedicado a través de un protocolo de flujo especializada (por ejemplo RTSP)
  2. la utilización de opciones disponibles en HTTP

Creo que la primera es la opción más eficiente, aunque requiere un servicio de transmisión dedicado (y/o hardware). Puede 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 hace. 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 transmisión (por lo tanto, se adhiere al aspecto de conexión de REST).

La última opción - transmisión por HTTP - puede no ser tan eficiente como la anterior, pero es definitivamente posible. Técnicamente, no es tan diferente que 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 informa 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 a través de HTTP mediante el uso de GET /media/1.3gp. Una opción es que el cliente descargue el recurso completo: HTTP progressive download. Una alternativa más limpia sería que el cliente acceda al recurso en fragmentos utilizando HTTP Range headers. Para ir a buscar el segundo trozo 256 KB de un archivo que es de 1 MB grande, la solicitud del cliente tendría el siguiente aspecto:

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

un servidor que soporte rangos serían entonces responderá con el Content-Range header, 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 se dijo al cliente el tamaño exacto del archivo en bytes (1 MB). En caso de que el cliente no conozca el tamaño del recurso, primero debe llamar al 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.

+2

Wow ... esta es una gran información. Me ha llamado la atención un par de nuevas formas de pensar sobre esto. Tampoco estaba al tanto del protocolo de transmisión en tiempo real. – JnBrymn

+1

No hay problema, me alegro de poder ayudar. Sin embargo, tenga en cuenta que no tuve la oportunidad de trabajar con protocolos de transmisión en tiempo real (con la excepción de la transmisión progresiva a través de HTTP). Elegí RTSP solo como un ejemplo, no puedo decir si podría ser útil en su escenario específico. Es posible que desee formular otra pregunta sobre SO sobre los protocolos de transmisión de datos específicamente. Wikipedia también ofrece un buen punto de partida para otros protocolos: consulte las secciones sobre "Problemas con el protocolo" y "Vea también" aquí: http://en.wikipedia.org/wiki/Streaming_Media – MicE

Cuestiones relacionadas