Estoy tratando de construir un pequeño sitio web con el servidor funcionalidad de inserción en el Matraz de micro-framework web, pero no sé si hay un marco para trabajar con directamente.

He utilizado Juggernaut, pero parece ser que no trabajan con redis-py en la versión actual, y Juggernaut se ha dejado de utilizar recientemente.

¿Alguien tiene una sugerencia con mi caso?

InformationsquelleAutor little-eyes | 2012-09-01

3 Comentarios

  1. 90

    Echar un vistazo a Server-Sent Events. Server-Sent Events es una
    explorador de API que te permite mantener a abrir un socket con el servidor, la suscripción a un
    flujo de actualizaciones. Para obtener más Información, lea Alex MacCaw (Autor de
    Juggernaut) publicar en ¿por qué mata a juggernaut y por qué la más simple
    Server-Sent Events están en manny casos, la mejor herramienta para el trabajo de
    Websockets.

    El protocolo es realmente fácil. Basta con agregar el mimetype text/event-stream a su
    respuesta. El navegador se encargará de mantener la conexión abierta y escuche para las actualizaciones. Un Evento
    enviado desde el servidor es una línea de texto de partida con data: y un salto de línea.

    data: this is a simple message
    <blank line>

    Si quieres intercambio de datos estructurados, acaba de volcar sus datos en json y enviar el json a través del cable.

    Una ventaja es que se puede utilizar ESS en el Frasco sin la necesidad de un extra
    Servidor. No es un simple el chat de la aplicación de ejemplo en github que
    utiliza redis como un pub/sub backend.

    def event_stream():
        pubsub = red.pubsub()
        pubsub.subscribe('chat')
        for message in pubsub.listen():
            print message
            yield 'data: %s\n\n' % message['data']
    
    
    @app.route('/post', methods=['POST'])
    def post():
        message = flask.request.form['message']
        user = flask.session.get('user', 'anonymous')
        now = datetime.datetime.now().replace(microsecond=0).time()
        red.publish('chat', u'[%s] %s: %s' % (now.isoformat(), user, message))
    
    
    @app.route('/stream')
    def stream():
        return flask.Response(event_stream(),
                              mimetype="text/event-stream")

    Usted no necesita usar gunicron para ejecutar el
    aplicación de ejemplo. Sólo asegúrese de utilizar el roscado cuando se ejecuta la aplicación, porque
    de lo contrario, la ESS conexión de bloquear el servidor de desarrollo:

    if __name__ == '__main__':
        app.debug = True
        app.run(threaded=True)

    En el lado del cliente sólo se necesita un controlador de Javascript función que será llamada cuando una nueva
    el mensaje es empujado desde el servidor.

    var source = new EventSource('/stream');
    source.onmessage = function (event) {
         alert(event.data);
    };

    Server-Sent Events son compatible recientes de Firefox, Chrome y Safari de los navegadores.
    Internet Explorer no es compatible aún Server-Sent Events, pero se espera que el apoyo de ellos en
    La versión 10. Hay dos recomendado Polyfills para soportar los navegadores más antiguos

    • Hola @PeterSmith, he probado este enfoque, sin embargo, la alerta(evento.de datos) no aparece nunca. Puedo ejecutar mi Frasco de aplicación en el puerto 8000 y el empuje en el puerto 8001. Así que me puse «var fuente = new EventSource(‘localhost:8001/push’);» y el Frasco de la aplicación tiene una página que un usuario puede publicar algo. El mensaje es transmitido y recibido por todos los demás usuarios. ¿Tienes alguna idea?
    • Por qué no se ejecuta la inserción en un puerto diferente? Una de las razones para la ESS es que se ejecuta dentro de la aplicación a través de http normales. ¿cómo ejecutar su frasco de apps? a través del servidor de desarrollo? ¿Agregar la rosca=True? ¿Qué navegador estás usando?
    • Hola @PeterHoffmann, yo uso tornado con Frasco. Es posible que me ponga instancia de la aplicación y empujador de instancia juntos en el tornado? Dicen diferentes controlador? Aún así debería establecer multiproceso?
    • Hay un hilo por cada cliente conectado a manejar su flujo de eventos ? Esto se ve como un tiempo de sondeo. Si sí, esto no escala. La pregunta de @little-ojos de sentido para mí.
    • Esta escala cuando se utiliza gevent+monkeypatch
    • ¿Cómo se puede estar realmente seguro de que el Frasco se cierra la conexión? Si me vuelve a cargar la página mucho me aparecen un montón de rancio conexiones, y cuando me ctrl-C el matraz aplicación todavía sirve peticiones porque hay conexiones abiertas :-/
    • La atención, me había ProfilerMiddleware habilitado y no funcionó, así que asegúrese de no usarlo.

  2. 11

    Como un seguimiento a @pedro-hoffmann respuesta, he escrito un Frasco de extensión específicamente para manejar server-sent events. Se llama Matraz-ESS, y es disponible en PyPI. Para instalarlo, ejecuta:

    $ pip install flask-sse

    Se puede utilizar como esto:

    from flask import Flask
    from flask_sse import sse
    
    app = Flask(__name__)
    app.config["REDIS_URL"] = "redis://localhost"
    app.register_blueprint(sse, url_prefix='/stream')
    
    @app.route('/send')
    def send_message():
        sse.publish({"message": "Hello!"}, type='greeting')
        return "Message sent!"

    Y conectarse a la secuencia de eventos de Javascript, esto funciona así:

    var source = new EventSource("{{ url_for('sse.stream') }}");
    source.addEventListener('greeting', function(event) {
        var data = JSON.parse(event.data);
        // do what you want with this data
    }, false);

    La documentación está disponible en ReadTheDocs. Tenga en cuenta que tendrá una ejecución de Redis servidor para manejar pub/sub.

  3. 10

    Redis es una exageración: el uso de Eventos de Servidor

    Tarde a la fiesta (como de costumbre), pero en mi humilde opinión el uso Redis puede ser un exceso.

    Mientras que usted está trabajando en Python+Frasco, considere el uso de generador de funciones, como se describe en este excelente artículo por Panisuan Joe Chasinga. El quid de la cuestión es:

    En su cliente index.html

    var targetContainer = document.getElementById("target_div");
    var eventSource = new EventSource("/stream")
      eventSource.onmessage = function(e) {
      targetContainer.innerHTML = e.data;
    };
    ...
    <div id="target_div">Watch this space...</div>

    En su Frasco servidor:

    def get_message():
        '''this could be any function that blocks until data is ready'''
        time.sleep(1.0)
        s = time.ctime(time.time())
        return s
    
    @app.route('/')
    def root():
        return render_template('index.html')
    
    @app.route('/stream')
    def stream():
        def eventStream():
            while True:
                # wait for source data to be available, then push it
                yield 'data: {}\n\n'.format(get_message())
        return Response(eventStream(), mimetype="text/event-stream")
    • Cuando trato de usar dormir en el get_message función de la corriente no alcanza el navegador. Sin dormir funciona bien, pero no quiero tantos mensajes en 1 segundo. Entonces, ¿tiene usted alguna idea de por qué no funciona cuando hay un sueño en la función?
    • El código funcionó para mí. Se puede poner un print() en get_message() para asegurarse de que está recibiendo llamadas como usted esperar? Y el uso de su navegador dev herramientas para supervisar el tráfico entre el servidor y el navegador? Que podría dar algunas ideas…

Dejar respuesta

Please enter your comment!
Please enter your name here