¿Por qué se acepta el sondeo en la programación web?

107

Actualmente estoy trabajando en el proyecto Ruby on Rails que muestra una lista de imágenes.

Un elemento imprescindible para este proyecto es que muestra las nuevas publicaciones en tiempo real sin necesidad de actualizar la página web. Después de buscar por un tiempo, me topé con algunas soluciones y servicios de JavaScript como PubNub; sin embargo, ninguna de las soluciones provistas tenía sentido en absoluto.

En la solución de JavaScript ( sondeo ) sucede lo siguiente:

  • El usuario 1 ve la lista de fotos.
  • En segundo plano, el código JavaScript está encuestando un punto final cada segundo para ver si hay una nueva publicación.
  • El usuario 2 agrega una nueva foto.
  • Hay un retraso de 50 ms antes de que se active el nuevo ciclo y recupere los nuevos datos.
  • El nuevo contenido se carga en el DOM .

Esto parece extraño cuando se traduce a un ejemplo del mundo real:

  • El usuario 1 tiene una pila de fotos en su escritorio.
  • Él / ella camina hacia el fotógrafo cada segundo y le pregunta si tiene uno nuevo.
  • El fotógrafo hace una nueva foto.
  • Este segundo cuando él / ella entra, ella puede tomar la foto y ponerla en la pila.

En mi opinión, la solución debería ser la siguiente:

  • El usuario 1 tiene una pila de fotos en su escritorio.
  • El fotógrafo toma una nueva foto.
  • El fotógrafo camina hacia la pila y lo pone con el resto.

La solución de PubNub es básicamente la misma, sin embargo, esta vez hay un interno que camina entre las partes para compartir los datos.

No hace falta decir que ambas soluciones consumen mucha energía, ya que se activan incluso cuando no hay datos para cargar.

Según mi conocimiento, no hay una explicación (lógica) de por qué esta forma de implementación se utiliza en casi todas las aplicaciones en tiempo real.

    
pregunta dennis 22.07.2014 - 20:39
fuente

8 respuestas

177

Empujar funciona bien para 1, o un número limitado de usuarios.

Ahora cambie el escenario con un fotógrafo y 1000 usuarios que todos quieren una copia de la imagen. El fotógrafo tendrá que caminar hasta 1000 pilas. Algunos de ellos pueden estar en una oficina cerrada, o repartidos por todo el piso. O su usuario de vacaciones, y no está interesado en nuevas fotos en este momento.

El fotógrafo estaría ocupado caminando todo el tiempo y no tomará fotos nuevas.

Fundamentalmente: un modelo de extracción / sondeo se adapta mejor a muchos lectores no confiables con requisitos de tiempo real sueltos (si una imagen tarda 10 segundos más tarde en llegar a una pila, ¿cuál es el problema?).

Dicho esto, un modelo push aún es mejor en muchas situaciones. Si necesita baja latencia (necesita esa nueva foto 5s después de haberla tomado), o las actualizaciones son poco frecuentes y las solicitudes son frecuentes y predecibles (siga preguntando al fotógrafo cada 10 segundos cuando genera una nueva imagen por día), entonces no es apropiado tirar. Depende de lo que estés tratando de hacer. NASDAQ: empujar. Servicio meteorológico: tirar. Fotógrafo de bodas: probablemente tire. Agencia de fotografía de noticias: probablemente empuje.

    
respondido por el ptyx 22.07.2014 - 20:57
fuente
106

Estoy realmente sorprendido de que solo una persona haya mencionado WebSockets . El soporte se implementado en todos los principales navegadores .

De hecho, PubNub los usa. Para su aplicación, el navegador probablemente se suscribirá a un socket que se emitirá cada vez que haya una nueva foto disponible. La toma no enviaría la foto, claro, pero solo un enlace para que el navegador la descargue de forma asíncrona.

En tu ejemplo imagina algo como:

  1. El (los) usuario (s) le informan al fotógrafo que quiere saber sobre todas las fotos futuras
  2. El fotógrafo dice por altavoz que hay una nueva foto disponible
  3. El usuario pide una foto al fotógrafo

Esto es algo así como su ejemplo de solución original. Es más eficiente que el sondeo porque el cliente no tiene que enviar ningún dato al servidor (excepto quizás heartbeats .)

También, como han mencionado otros, hay otros métodos que son mejores que un simple sondeo que funciona en navegadores más antiguos ( longpolling, et al .)

    
respondido por el korylprince 22.07.2014 - 23:51
fuente
41

A veces lo suficientemente bueno es lo suficientemente bueno.

De todas las formas posibles de implementar un proceso de comunicaciones "en tiempo real", el sondeo es quizás la forma más simple. El sondeo se puede usar de manera efectiva cuando el intervalo de sondeo es relativamente largo (es decir, segundos, minutos u horas en lugar de instantáneos), y los ciclos de reloj consumidos al verificar la conexión o el recurso realmente no importan.

    
respondido por el Robert Harvey 22.07.2014 - 20:57
fuente
30

El protocolo HTTP está limitado porque el cliente DEBE ser el que inicie la solicitud. El servidor no puede comunicarse con el cliente a menos que responda a la solicitud de un cliente.

Para ajustar su ejemplo del mundo real, agregue la siguiente restricción:

  • El usuario 2 SOLO puede responder a las preguntas del usuario 1 con una sola oración, después de lo cual el usuario 1 debe abandonar. El usuario 2 no tiene otra forma de comunicarse.

Con esta nueva restricción, ¿cómo lo haría si no fuera una encuesta?

    
respondido por el riwalk 22.07.2014 - 20:55
fuente
13

¿Por qué se acepta el sondeo? ¡Porque en realidad todas las soluciones son en realidad encuestas de bajo nivel!

Si el servidor debería actualizarlo tan pronto como haya nuevas imágenes disponibles, generalmente tiene que tener una conexión con usted, ya que las direcciones IP cambian con frecuencia y nunca se sabe si alguien ya no está interesado, por lo que el cliente tiene que enviar alguna forma de señal de mantener vivo, por ejemplo, "Todavía estoy aquí, no estoy desconectado"

Todas las conexiones con estado (por ejemplo, TCP / IP) funcionan igual, ya que solo puede enviar paquetes de datos singulares a través de Internet; nunca se sabe si la otra parte sigue allí.

Así que cada protocolo tiene un tiempo de espera. Si una entidad no responde dentro de X segundos, se presume que está muerta. Así que incluso si solo tiene una conexión abierta entre el servidor y el cliente, sin enviar ningún dato, el servidor y el cliente tienen que enviar paquetes regulares de mantenimiento (esto se maneja a bajo nivel si abre una conexión entre ellos), y cómo está ¿Esto al final es diferente del sondeo?

Por lo tanto, el mejor enfoque probablemente sería largo:

El cliente envía una solicitud inmediatamente después de cargar el sitio (por ejemplo, le dice al fotógrafo "Dígame si hay fotos nuevas"), pero el servidor no responde si no hay fotos nuevas. Tan pronto como la solicitud se agote, el cliente vuelve a preguntar.

Si el servidor ahora tiene nuevas imágenes, puede responder inmediatamente a todos los clientes que están en la fila para nuevas imágenes. Por lo tanto, su tiempo de reacción después de una nueva imagen es incluso más corto que con el envío, ya que el cliente todavía está esperando en una conexión abierta para recibir una respuesta y no tiene que crear una conexión con el cliente. ¡Y las solicitudes de sondeo del cliente no son mucho más tráfico que una conexión constante entre el cliente y el servidor para una respuesta!

    
respondido por el Falco 24.07.2014 - 11:09
fuente
9

Una de las ventajas del sondeo es que limita el daño que puede causar si un mensaje desaparece o si se falla el estado de algo. Si X le pregunta a Y sobre su estado una vez cada cinco segundos, entonces la pérdida de una solicitud o respuesta simplemente dará como resultado que la información de X sea diez segundos desactualizada en lugar de 5. Si Y se reinicia, X puede descubrirlo al siguiente. el tiempo Y es capaz de responder a uno de los mensajes de X. Si X se reinicia, es posible que nunca se moleste en pedirle algo a Y después, pero quien esté observando el estado de X debe reconocer que se ha reiniciado.

Si en lugar de X sondeo de Y, X confió en Y para informarle cada vez que cambió su estado, entonces, si el estado de Y cambió y envió un mensaje a X, pero por alguna razón ese mensaje no se recibió, X podría no darse cuenta del cambio. Del mismo modo, si Y se reinicia y nunca tiene ningún motivo para enviar un mensaje a X sobre cualquier cosa.

En algunos casos, puede ser útil para X solicitar que Y envíe mensajes de forma autónoma con su estado, ya sea periódicamente o cuando cambie, y solo tenga X poll si transcurre demasiado tiempo sin escuchar nada de Y. Tal diseño puede eliminar la necesidad de que X envíe la mayoría de sus mensajes (por lo general, X debería informar a Y, al menos ocasionalmente, de que todavía está interesado en recibir mensajes, e Y debería dejar de enviar mensajes si se prolonga demasiado sin ninguna indicación de interés). Sin embargo, un diseño de este tipo requeriría que Y mantenga de forma persistente información sobre X, en lugar de poder simplemente enviar una respuesta a quien la haya encuestado y luego olvidarse de inmediato de quién era. Si Y es un sistema integrado, tal simplificación puede ayudar a reducir los requisitos de memoria lo suficiente como para permitir el uso de un controlador más pequeño y más barato.

El sondeo puede tener una ventaja adicional cuando se utiliza un medio de comunicaciones potencialmente no confiable (por ejemplo, UDP o radio): puede eliminar en gran medida la necesidad de acuses de recibo de la capa de enlace. Si X envía a Y una solicitud de estado Q, Y responde con un informe de estado R, y X escucha R, X no necesitará escuchar ningún tipo de acuse de recibo en la capa de enlace para que Q sepa que se recibió. A la inversa, una vez que Y envía R, no necesita saber ni preocuparse si X la recibió. Si X envía una solicitud de estado y no obtiene respuesta, puede enviar otra. Si Y envía un informe y X no lo escucha, X enviará otra solicitud. Si cada solicitud sale una vez y produce una respuesta o no, ninguna de las partes debe saber o preocuparse si se recibió algún mensaje en particular. Dado que el envío de un acuse de recibo puede consumir casi tanto ancho de banda como una solicitud o informe de estado, usar un viaje de ida y vuelta no cuesta mucho más de lo que costaría un informe y acuse de recibo no solicitados. Si X envía algunas solicitudes sin obtener respuestas, es posible que en algunas redes enrutadas dinámicamente sea necesario habilitar los acuses de recibo a nivel de enlace (y solicitar en su solicitud que S haga lo mismo) para que la pila de protocolos subyacente pueda reconocer el problema de entrega y buscar una nueva ruta, pero cuando las cosas funcionen, un modelo de informe de solicitud será más eficiente que el uso de acuses de recibo a nivel de enlace.

    
respondido por el supercat 23.07.2014 - 00:28
fuente
1

La pregunta es equilibrar la cantidad de encuestas innecesarias frente a la cantidad de empujes innecesarios.

Si tu encuesta:

  • Obtienes una respuesta en este mismo momento. Está bien si lo solicita solo de vez en cuando o necesita un conjunto de datos en este mismo momento.
  • Es posible que obtengas una respuesta "sin contenido", lo que provoca una carga inútil en la línea.
  • Pones carga en la línea solo cuando haces una encuesta, pero siempre cuando haces una encuesta.

Si presionas:

  • Usted entrega la respuesta correctamente cuando está disponible, lo que permite un procesamiento inmediato en el lado del cliente.
  • Es posible que entregue datos a los clientes que no estén interesados en estos datos, lo que provocará una carga inútil en la línea.
  • Pones carga en la línea cada vez que hay datos nuevos, pero solo cuando hay datos nuevos.

Hay varias soluciones sobre cómo lidiar con los distintos escenarios y sus desventajas, como por ejemplo un tiempo mínimo entre encuestas, proxies de solo encuesta para quitar la carga del sistema principal o, para los impulsos, una regulación para registre y especifique los datos deseados y luego desregistre en el cierre de sesión. Lo que mejor se adapta no es nada que pueda decir en general, depende del sistema.

En su ejemplo, el sondeo no es la solución más eficiente, sino la más práctica. Es muy fácil escribir un sistema de sondeo en JavaScript, y también es muy fácil implementarlo en el lado de la entrega. Un servidor creado para entregar datos de imágenes debe poder manejar las solicitudes adicionales y, de lo contrario, puede escalarse de manera lineal, ya que los datos son en su mayoría estáticos y, por lo tanto, pueden almacenarse en caché fácilmente.

Un método de inserción que implemente un inicio de sesión, una descripción de los datos deseados y, finalmente, un cierre de sesión sería más eficiente, pero probablemente sea demasiado complejo para el "script-kiddy" promedio, y debe abordar la pregunta: ¿qué ¿Si el usuario simplemente cierra el navegador y no se puede cerrar sesión?

¿Quizás es mejor tener más usuarios (ya que acceder es fácil) que ahorrar algo de dinero en otro servidor de caché?

    
respondido por el TwoThe 23.07.2014 - 15:42
fuente
1

Por alguna razón, en estos días, todos los desarrolladores web más jóvenes parecen haber olvidado las lecciones del pasado y por qué algunas cosas han evolucionado de la forma en que lo hicieron.

  1. El ancho de banda era un problema
  2. La conexión puede ser intermitente.
  3. Los navegadores no tenían tanta potencia informática
  4. Había otros métodos para acceder al contenido. La web es no es w3.

Ante estas restricciones, es posible que no tenga una comunicación constante de 2 vías. Y si observa el modelo OSI, encontrará que la mayoría de las consideraciones están destinadas a desacoplar la persistencia con la conexión subyacente.

Teniendo esto en cuenta, un método de sondeo para obtener información es una excelente manera de reducir el ancho de banda y el cálculo en el lado del cliente. El aumento de empuje es, en su mayor parte, solo el cliente que realiza un sondeo constante o sockets web. Personalmente, si fuera todos los demás, apreciaría la regularidad del sondeo como un medio de análisis de tráfico, donde una solicitud GET / POST fuera de tiempo señalaría a un hombre en una situación intermedia de algún tipo.

    
respondido por el guestaccount 24.11.2014 - 00:21
fuente

Lea otras preguntas en las etiquetas