2009-01-02 14 views
35

Si hay un recurso REST que deseo monitorear para cambios o modificaciones de otros clientes, ¿cuál es la mejor (y la más RESTANTE) forma de hacerlo?¿Cuál es una forma RESTful de monitorear un recurso REST para cambios?

Una idea que he tenido al hacerlo es proporcionar recursos específicos que mantendrán la conexión abierta en lugar de regresar inmediatamente si el recurso (aún) no existe. Por ejemplo, dado el recurso:

/game/17/playerToMove 

un "GET" en este recurso me podría decir que es el turno de mi oponente a moverse. En lugar de continuamente de votación este recurso para saber cuando es mi turno para mover, puede ser que tenga en cuenta el número de movimiento (por ejemplo 5) y tratar de recuperar el movimiento siguiente:

/game/17/move/5 

En un modelo "normal" reposo, parece que una solicitud GET para esta URL devolverá un error 404 (no encontrado). Sin embargo, si por el contrario, el servidor mantiene la conexión abierta hasta que mi oponente jugó su movimiento, es decir .:

PUT /game/17/move/5 

continuación, el servidor podría devolver el contenido que mi oponente poner en ese recurso. Esto me proporcionaría los datos que necesito, así como también una especie de notificación de cuándo se movió mi oponente sin requerir un sondeo.

¿Es este tipo de esquema RESTful? ¿O viola algún tipo de principio de REST?

+1

"¿Cuál es la manera más extrema de hacer esto, Scrappy?" –

+0

Puede usar sondeo largo, o combinar REST con un servicio websocket, que envía los eventos al cliente. – inf3rno

Respuesta

24

Su solución propuesta suena como long polling, que podría funcionar muy bien.

Solicitaría /game/17/move/5 y el servidor no enviará ningún dato, hasta que se complete el movimiento 5. Si la conexión se interrumpe o si obtiene un tiempo de espera, simplemente vuelva a conectarse hasta que obtenga una respuesta válida.

El beneficio de esto es que es muy rápido: tan pronto como el servidor tenga nuevos datos, el cliente lo obtendrá. También es resistente a las conexiones caídas, y funciona si el cliente está desconectado durante un tiempo (se puede solicitar /game/17/move/5 una hora después de que se ha movido y obtener los datos al instante, para luego pasar a move/6/ y así sucesivamente)

El problema con larga sondear es cada "encuesta" que vincula un hilo de servidor, lo que rompe rápidamente servidores como Apache (ya que se queda sin hilos de trabajo, por lo que no puede aceptar otras solicitudes). Necesita un servidor web especializado para atender las solicitudes de larga duración. El módulo Python twisted (un "motor de red impulsado por eventos") es ideal para esto, pero es más trabajo que las encuestas regulares.

En respuesta a su comentario sobre Jetty/Tomcat, no tengo ninguna experiencia con Java, pero parece que ambos usan un sistema similar de pool-of-worker-threads para Apache, por lo que tendrá el mismo problema . Encontré this post que parece abordar exactamente este problema (para Tomcat)

+0

Estoy usando Jetty como Java contenedor de servlet. Parece funcionar bien para "largas encuestas". ¿Tiene los mismos problemas que Apache (es decir, quedarse sin hilos de trabajo)? ¿Qué hay de Tomcat? – Ross

+0

Para evitar la vinculación de subprocesos, puede utilizar un controlador asincrónico HTTP asp.net. Esto devuelve el hilo al grupo de subprocesos. –

2

Encontré this article proponiendo un nuevo encabezado HTTP, "When-Modified-After", que básicamente hace lo mismo: el servidor espera y mantiene la conexión abierta hasta que se modifique el recurso.

Prefiero un enfoque basado en la versión en lugar de un enfoque basado en la marca de tiempo, ya que es menos propenso a las condiciones de carrera y le da un poco más de información sobre lo que está recuperando. ¿Alguna idea de este enfoque?

+0

El enfoque basado en la versión usaría el encabezado ETag HTTP. http://en.wikipedia.org/wiki/HTTP_ETag – Chase

2

Sugeriría un 404, si su cliente previsto es un navegador web, ya que mantener la conexión abierta puede bloquear activamente las solicitudes del navegador en el cliente al mismo dominio. Depende del cliente la frecuencia de las encuestas.

+0

Eso es un mal uso del error (cómo se detecta un 404 real porque se solicitó/juego/x14 no/juego/14). Devolución {'error' : 'no hay contenido nuevo'} o algo sería menos problemático .. – dbr

+3

no, porque hasta que se haya realizado el paso 14, el recurso no existe ... es un 404. apropiado – Tracker1

Cuestiones relacionadas