Pregunta

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

Una idea que tuve para hacerlo es proporcionar recursos específicos que mantendrán la conexión abierta en lugar de regresar de inmediato si el recurso (todavía) no existe. Por ejemplo, dado el recurso:

/game/17/playerToMove

a " OBTENER " en este recurso podría decirme que es el turno de mi oponente para moverse. En lugar de sondear continuamente este recurso para saber cuándo es mi turno de moverme, podría anotar el número de movimiento (digamos 5) e intentar recuperar el siguiente movimiento:

/game/17/move/5

En un " normal " Modelo REST, parece que una solicitud GET para esta URL devolvería un error 404 (no encontrado). Sin embargo, si en cambio, el servidor mantuvo la conexión abierta hasta que mi oponente jugó su movimiento, es decir:

PUT /game/17/move/5

entonces el servidor podría devolver los contenidos que mi oponente PUSO en ese recurso. Esto me proporcionaría los datos que necesito, así como una especie de notificación para cuando mi oponente se haya movido sin requerir encuestas.

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

¿Fue útil?

Solución

Su solución propuesta suena como sondeo largo , que podría funcionar realmente bien.

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

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

El problema con el sondeo largo es cada "sondeo" ata un hilo del servidor, 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 sondeo largo. El módulo Python twisted (un " un motor de red controlado por eventos ") es excelente para esto, pero es más trabajo que el sondeo regular ...

En respuesta a su comentario sobre Jetty / Tomcat, no tengo ninguna experiencia con Java, pero parece que ambos usan un sistema de subprocesos de trabajo similar al de Apache, por lo que tendrá el mismo problema. Encontré esta publicación que parece abordar exactamente este problema (para Tomcat)

Otros consejos

Encontré este artículo propone un nuevo encabezado HTTP, "When-Modified-After", que esencialmente 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 brinda un poco más de información sobre lo que está recuperando. ¿Alguna idea sobre este enfoque?

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 con qué frecuencia sondear.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top