Django / Comet (Empuje): ¿Al menos de todos los males?

He leído todas las preguntas y respuestas que puedo encontrar sobre Django y HTTP Push. Sin embargo, ninguno ofrece una solución clara, concisa y de principio a fin sobre cómo lograr un “mundo hola” básico de la llamada funcionalidad “cometa“.

Primera pregunta (1): ¿Hasta qué punto es el problema que HTTP simplemente no está (al menos hasta ahora) hecho para esto? ¿Son todas las soluciones potenciales esencialmente pirateos?

2) ¿Cuál es la mejor solución disponible actualmente?

  • ¿Orbitado?
  • Alguna otra solución basada en Twisted?
  • ¿Tornado?
  • node.JS?
  • XMPP con BOSH?

Alguna otra solución?

3) ¿Cómo funciona el módulo empujador nginx en esta discusión?

4) ¿Cuál de estas soluciones requiere el reemplazo del típico modelo de implementación mod_wsgi / nginx (o apache)? ¿Por qué lo requieren? ¿Es esta una transición favorable en cualquier caso?

5) ¿Cuán importantes son las ventajas de usar una solución que ya está en Python?

La presentación de Alex Gaynor de PyCon 2010, que acabo de ver en blip.tv, es sorprendente e informativa, pero no muy específica sobre el estado actual de HTTP Push en Django. Una cosa que dijo que me dio cierta confianza fue esta: Orbited hace un buen trabajo de abstracción y simulación del concepto de tomas de red. Por lo tanto, cuando WebSockets realmente aterrice, estaremos en un buen lugar para una transición.

6) ¿En qué se diferencia HTML5 Websockets de las soluciones actuales? ¿Es exacta la evaluación de Gaynor sobre la facilidad de transición de Orbited?

Echaré un vistazo a evserver (http://code.google.com/p/evserver/) si todo lo que necesitas es un cometa.

Es “compatible con [la] poco conocida extensión WSGI asíncrona” y se basa en libevent. Funciona como un encanto y es compatible con django. El código del controlador real es un poco feo, pero se escala bien, ya que realmente es asincrónico.

He usado evserver y actualmente me estoy moviendo a un ciclón (tornado en twisted) porque necesito un poco más que los offser de evserver. Necesito un verdadero bidireccional io (think socket.io (http://socket.io/)) y aunque evserver podría soportarlo, pensé que era más fácil volver a implementar el socket.io de tornados en el ciclón (opté por el ciclón en lugar del tornado como ciclón se basa en retorcido, lo que permite más transportes que no están implementados en twisted (ic zeromq)) Socket.io admite websockets, sondeo estilo cometa y, mucho más interseting, websockets basados ​​en flash. Creo que en la mayoría de las situaciones prácticas, websockets + websockets basados ​​en flash son suficientes para soportar el 99% (según Adobe Flash, la penetración es de aproximadamente el 99% (http://www.adobe.com/products/player_census/flashplayer/version_penetration.html)) de los visitantes de un sitio web (solo las personas que no usan el flash deben recurrir a uno de sus transportes de copia de seguridad socket.io its (menos perfomant y resource hogging))

Tenga en cuenta que los websockets no son un transporte http, lo que los pone detrás de servidores proxy basados ​​en http (por ejemplo, haproxy en el modo http) interrumpe la conexión. Es mejor que los atienda en una IP o puerto alternativo para que pueda usar el proxy en el modo tcp (por ejemplo, haproxy en el modo tcp).

Para responder a sus preguntas: (1) Si no necesita un transporte bidireccional, las soluciones basadas en longpolling son lo suficientemente buenas (lo único que hacen es mantener una conexión abierta). Las cosas son dudosas cuando necesitas que tu conexión sea completa o necesitas poder enviar y recibir datos. En el último caso, socket.io ayuda. Sin embargo, los websockets están hechos para este escenario y con el soporte de flash está disponible para la mayoría de los visitantes de un sitio web (a través de socket.io o independiente, sin embargo, socket.io tiene el beneficio adicional de transportes de respaldo para aquellas personas que no desean instalar el flash)

(2) si todo lo que necesitas es push, evserver es tu mejor opción. Utiliza los mismos javascripts en el lado del cliente como en órbita. De lo contrario, mire socket.io (esto también necesita un servidor compatible, el único python disponible es el tornado).

(3) Es solo otra implementación del servidor. Si lo leo correctamente, solo es de empuje. el envío de datos a un cliente se realiza haciendo una solicitud de http desde su aplicación al servidor nginx. (nginx luego se ocupa de que lleguen al cliente). Si estás interesado en esto, mira mongrel2 (http://mongrel2.org/home), no solo tiene controladores para longpolling sino también para websockets. (En lugar de hacer una solicitud http para mongrel, esta vez usas manejadores zeromq para obtener datos en su servidor mongrel) (Tenga en cuenta la falta de entusiasmo del desarrollador por websockets y websockets basados ​​en flash. Especialmente teniendo en cuenta que el protocolo de websocket tiende a evolucionar, en algún punto, podría necesitar recodificar el soporte de websocket de mongrel2. teniendo soporte para websockets)

(4) Todas las soluciones, excepto evserver, reemplazan wsgi por otra cosa. Aunque la mayoría de los servidores también tienen soporte wsgi en la parte superior de esta “otra cosa”. Independientemente de la solución que elija, tenga cuidado de que una solicitud de CPU intensiva u otra forma de locking no bloquee el servidor. (necesita múltiples instancias o hilos).

(5) No muy significativo. Todas las soluciones dependen de algunos manejadores personalizados para enviar (y, si corresponde, recibir) datos al cliente. Todas las soluciones que mencioné permiten que estos manejadores se escriban en python. Si quieres usar un framework completamente diferente (node.js), entonces tienes que sopesar la facilidad de node.js (se supone que es fácil, pero también es bastante experimental, y encontré muy pocas bibliotecas para ser realmente estable) contra la conveniencia de usar su base de códigos existente y las bibliotecas disponibles (por ejemplo, si su aplicación necesita un blog, hay muchos blogs de django que puede conectar, pero ninguno para node.js). Tampoco se quede ciego ante las estadísticas de rendimiento. a menos que planee enviar datos predefinidos tontos (lo que hacen todos los puntos de referencia) al cliente, encontrará que el procesamiento real de datos agrega mucho más sobrecarga que incluso la peor implementación asincrónica. (Pero aún desea utilizar un servidor basado en asincronía si planea tener muchos clientes simultáneos, el enrutamiento simplemente no tiene la intención de mantener miles de conexiones activas)

(6) los websockets ofrecen comunicación bidireccional, el sondeo / cometa largo solo envía datos pero no acepta escrituras. (Socket.io simula este soporte bidireccional utilizando dos solicitudes http, una para longpoll, otra para enviar datos. Realiza un seguimiento de su interdependencia mediante una identificación (de sesión) que es parte de ambas cadenas de consulta de solicitudes). Los websockets basados ​​en flash son similares a los websockets reales (la diferencia es que su implementación está en el swf, no en su navegador). Además, el protocolo websockets no sigue el protocolo http; longpolling / comet stuff (técnicamente el cliente de websocket envía una solicitud de actualización al servidor de websocket, el protocolo actualizado ya no es http)

Hay soporte para WebSockets con django-websocket , pero desafortunadamente hay problemas importantes para que funcione; aquí hay una cita de esa página:

Descargo de responsabilidad (lo que debe saber al usar django-websocket)

GRAN EXENCIÓN DE RESPONSABILIDAD GRATUITA – en este momento, técnicamente NO es posible en modo alguno utilizar un websocket con WSGI. Este es un problema conocido, pero no se puede solucionar de forma limpia debido a alguna decisión de diseño que se tomó mientras se escribió el stadard de WSGI. En este momento, cosas como Websockets, etc. no existían y no eran predecibles.

Pero no solo WSGI es el factor limitante. Django en sí fue diseñado alrededor de un simple escenario de solicitud de respuesta sin Websockets en mente. Esto también significa que no es posible proporcionar una implementación estándar de websocket estándar en este momento para django. Sin embargo, funciona de alguna manera no tan bonita. Así que ten en cuenta que las tomas tcp pueden ser torturadas usando django-websocket.

Entonces, en este momento, WSGI: no ir; Django: casi ninguno, incluso con django-websockets; ver también un comentario en el anuncio original del autor:

No puedo decir que esto parece una buena idea. Estás haciendo conexiones de larga duración de una manera que requerirá enhebrado. django-websocket requiere enhebrar la instalación, y no funcionará si tienes procesos (porque tendrías demasiados procesos) pero los hilos no escalarán para muchas conexiones al mismo tiempo, tampoco, así que es solo una seguridad falsa Necesitas una plataforma asincrónica para cosas de larga vida, y hago esto haciendo mi aplicación en Django y mi cometa y websocket en Node.js

Personalmente, si bash usar WebSockets (que espero sea el año que viene), probaría primero la combinación de Twisted y Cyclone . Están diseñados para hacer frente a WebSockets y escalar bien. Si escribe su código correctamente para eliminar dependencias innecesarias en Django, debería poder usar gran parte de su código en un sistema basado en Twisted. Esta es una ventaja muy clara sobre el uso de Node.js o Comet o cualquier sistema en otro idioma. También puedes hacer un simple empujón

Finalmente, también puede decidir que es demasiado difícil y usar un servicio externo para proporcionar el soporte de inserción. Eso se convierte en una cuestión de enviar una simple solicitud JSON a sus servidores en lugar de preocuparse por cómo hacer la conexión y cómo funcionará la concurrencia y cosas por el estilo. Por supuesto, tendrá que pagar por ello (aunque actualmente puede ser gratis mientras esté en Beta), pero no necesita preocuparse por los detalles de la implementación; no obstante, no tendrá todo el poder de WebSockets de esa forma, solo envíe soporte.

Re pregunta # 2, recientemente me dieron un recorrido por el interior de una aplicación de Django que utiliza Comet en gran medida, y Orbited fue la solución que eligieron.

No puedo creer que hayan pasado más de seis años desde que hice esta pregunta.

La sincronización con Django (y el tráfico de red asociado, por ejemplo, websockets) ha sido una picazón para muchos de nosotros en la comunidad. He tomado estos últimos años, entre otras cosas, arañar esta picazón.

hendrix

hendrix es un conatiner WSGI / ASGI que se ejecuta en Twisted. Ha sido un proyecto impulsado principalmente por 5 entusiastas, con ayuda y financiación de algunas organizaciones visionarias. Actualmente está en producción en docenas, pero no en cientos, de compañías.

Dejaré que usted lea la documentación para ver por qué es la mejor solución a este problema, pero algunos aspectos destacados rápidos:

  • está basado en Twisted, no requiere conocimiento o uso de internos Twisted, pero los deja a todos disponibles
  • “Simplemente funciona” en el sentido de que no necesita ninguna configuración especial de servidor o proceso para realizar tráfico asincrónico y de socket desde su aplicación Django (o Pyramid, o Flask)
  • Es muy probable que sea compatible con ASGI, el estándar de canales Django, y es de alguna manera significativa el primer contenedor ASGI
  • Se envía con API simples que mantienen el flujo de su lógica de visualización y son fáciles de probar por unidad.

Por favor, vea esta charla que di en Django-NYC (en las oficinas de Buzzfeed) para obtener más información sobre por qué creo que esta es la mejor respuesta a esta pregunta.

    Intereting Posts