Saltar al contenido

¿Cómo implementar la inserción del servidor en Flask framework?

Si hallas algún fallo con tu código o proyecto, recuerda probar siempre en un ambiente de testing antes añadir el código al trabajo final.

Solución:

Eche un vistazo a los eventos enviados por el servidor. Server-Sent Events es una API de navegador que le permite mantener abierto un socket en su servidor, suscribiéndose a un flujo de actualizaciones. Para obtener más información, lea la publicación de Alex MacCaw (autor de Juggernaut) sobre por qué mata a Juggernaut y por qué los eventos enviados por el servidor más simples son, en muchos casos, la mejor herramienta para el trabajo que Websockets.

El protocolo es muy fácil. Solo agrega el tipo mime text/event-stream a tu respuesta El navegador mantendrá la conexión abierta y escuchará las actualizaciones. Un evento enviado desde el servidor es una línea de texto que comienza con data: y una nueva línea siguiente.

data: this is a simple message

Si desea intercambiar datos estructurados, simplemente descargue sus datos como json y envíe el json por cable.

Una ventaja es que puede usar SSE en Flask sin necesidad de un servidor adicional. Hay un ejemplo de aplicación de chat simple en github que usa redis como backend pub/sub.

def event_stream():
    pubsub = red.pubsub()
    pubsub.subscribe('chat')
    for message in pubsub.listen():
        print message
        yield 'data: %snn' % 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")

No necesita usar gunicron para ejecutar la aplicación de ejemplo. Solo asegúrese de usar subprocesos cuando ejecute la aplicación, porque de lo contrario, la conexión SSE bloqueará su servidor de desarrollo:

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

En el lado del cliente, solo necesita una función de controlador de Javascript que se llamará cuando se envíe un nuevo mensaje desde el servidor.

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

Los eventos enviados por el servidor son compatibles con los navegadores Firefox, Chrome y Safari más recientes. Internet Explorer aún no admite eventos enviados por el servidor, pero se espera que los admita en la versión 10. Hay dos Polyfill recomendados para admitir navegadores más antiguos

  • EventSource.js
  • jquery.eventsource

Redis es exagerado: use eventos enviados por el servidor (SSE)

Llegar tarde a la fiesta (como de costumbre), pero en mi humilde opinión, usar Redis puede ser excesivo.

Mientras esté trabajando en Python+Flask, considere usar funciones de generador como se describe en este excelente artículo de Panisuan Joe Chasinga. La esencia de esto 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;
;
...
Watch this space...

En su servidor Flask:

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: nn'.format(get_message())
    return Response(eventStream(), mimetype="text/event-stream")

Como seguimiento a la respuesta de @peter-hoffmann, he escrito una extensión de Flask específicamente para manejar eventos enviados por el servidor. Se llama Flask-SSE y está disponible en PyPI. Para instalarlo, ejecuta:

$ pip install flask-sse

Puedes usarlo así:

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 para conectarse al flujo de eventos desde Javascript, 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 necesitará un servidor Redis en ejecución para manejar pub/sub.

Valoraciones y comentarios

Si haces scroll puedes encontrar las observaciones de otros administradores, tú también tienes el poder dejar el tuyo si te gusta.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *