2010-04-05 5 views
8

dado, cuando un usuario solicita /foo en mi servidor, que envía la siguiente respuesta HTTP (no cerrar la conexión):Empujar los datos una vez que se solicita una dirección URL

Content-Type: multipart/x-mixed-replace; boundary=----------------------- 

----------------------- 
Content-Type: text/html 

<a href="/bar">foo</a> 

Cuando el usuario va a /bar (que se envíe 204 No Content para que la vista no cambie), deseo enviar los siguientes datos en la respuesta inicial.

----------------------- 
Content-Type: text/html 

bar 

¿Cómo obtendré la segunda solicitud para activar esto desde la respuesta inicial? Estoy planeando posiblemente crear una fantasía [motores compatibles con multipart/x-mixed-replace (actualmente solo Gecko)] - solo aplicación de correo electrónico que hace push-push y efectos Ajax sin ningún JavaScript, solo por diversión.

Respuesta

1

Sin respuesta completa, pero:

En su pregunta, sólo se describe una arquitectura de estilo Comet. En cuanto al soporte de las técnicas de estilo Comet en Python/WSGI, hay un StackOverflow question, que habla de varios servidores Python con soporte para solicitudes de larga ejecución a la Comet.

También es interesante esta cadena de correo en Python Web-SIG: "Could WSGI handle Asynchronous response?". En mayo de 2008, hubo una amplia discusión en el Web-SIG sobre el tema asynchronous requests in WSGI.

Un reciente desarrollo es evserver, un servidor WSGI de peso ligero, que implementa el Asynchronous WSGI extension propuesto por Christopher Stawarz en el Web-SIG en mayo de 2008.

Por último, el Tornado web server apoya non-blocking asynchronous requests. Tiene una aplicación de ejemplo de chat que utiliza encuestas largas, que tiene similitudes con tus requisitos.

+0

Puede que no te des cuenta, pero 'multipart/x-mixed-replace' __is__ es una forma de Comet; la única forma que no requiere JavaScript. Si logro que funcione con las solicitudes asíncronas de Tornado, aceptaré esta respuesta. –

+0

** Estoy ** muy consciente de que 'multipart/x-mixed-replace' es una forma de Comet, pero pensé ** no estabas ** ;-), ya que no mencionaste la palabra de moda en tu pregunta. Hice un poco de cambio de palabras. – flight

1

Si el problema es pasar algún comando desde la aplicación/bar a la aplicación/foo y está utilizando algún enfoque tipo servlet (el código Python se carga una vez y no para cada solicitud como en CGI), simplemente puede cambiar alguna propiedad de clase de la aplicación/foo y esté listo para reaccionar ante el cambio en la instancia/foo (verificando el estado de la propiedad).

Obviamente, la aplicación/foo no debería volver inmediatamente después de la primera solicitud y ceder el contenido línea por línea.

Pensé que esto era solo teoría, no lo he intentado yo mismo.

+0

Sin usar una base de datos completa (ya que sería bastante exagerado), ¿cómo podría cambiar fácilmente un objeto de estado compartido? –

+0

Como dije, si el código se carga solo una vez, entonces cada nueva solicitud es solo una nueva instancia de la clase de la aplicación. A continuación, puede usar algunas propiedades de nivel de módulo o clase (no instancia) para intercambiar información. – newtover

-1

No estoy seguro si esto es exactamente lo que está buscando, pero hay una forma bastante antigua de hace empuje servidor usando un contenido MIME del/de varias copias de mixed-replace x

Básicamente componer la respuesta un objeto mime con tipo de contenido multipart/x-mixed-replace, y envía la primera "versión" de un documento. El navegador mantendrá el socket abierto.

Luego, cuando el servidor decide enviar más datos, se envía una nueva "versión" del documento desde el servidor, y el navegador reemplazará inteligentemente (dentro de cualquier marco/iframe que contenga el contenido) el contenido.

Esta era una forma temprana de hacer webcams, donde el servidor enviaba (empuje) imagen tras imagen, y el navegador simplemente seguía reemplazando la imagen en el documento una y otra vez. Esta es también una forma de hacer un mensaje de "Cargando ..." sobre una única solicitud HTTP.

+0

¿Qué tiene que ver con responder mi pregunta? Sé lo que es 'multipart/x-mixed-replace' y cómo usarlo, como se muestra en la pregunta. Estoy preguntando Python wsgi sobre cómo manejaría este escenario. –

1

He creado un pequeño ejemplo (sólo por diversión, ya sabes :))

import threading 

num = 0 
cond = threading.Condition() 

def app(environ, start_response): 
    global num 

    cond.acquire() 
    num += 1 
    cond.notifyAll() 
    cond.release() 

    start_response("200 OK", [("Content-Type", "multipart/x-mixed-replace; boundary=xxx")]) 
    while True: 
     n = num  
     s = "--xxx\r\nContent-Type: text/html\r\n\r\n%s\n" % n 
     yield s 
     # wait for num change: 
     cond.acquire() 
     while num == n: 
      cond.wait() 
     cond.release() 


from cherrypy.wsgiserver import CherryPyWSGIServer 
server = CherryPyWSGIServer(("0.0.0.0", 3000), app) 

try: 
    server.start() 
except KeyboardInterrupt: 
    server.stop() 

# Now whenever you visit http://127.0.0.1:3000/, the number increases. 
# It also automatically increases in all previously opened windows/tabs. 

La idea de una variable compartida y la sincronización de hilos (con la condición de objeto variable) se basa en el hecho de que el servidor WSGI proporcionado por CherryPyWSGIServer está enhebrado.

Cuestiones relacionadas