2015-04-08 22 views
6

Sto provando a eseguire il polling lungo con JQuery e Python sotto il framework Flask.Polling lungo in Python con Flask

aver fatto polling lungo prima che in PHP, ho cercato di andare su di esso nello stesso modo:

Uno script/funzione che ha un while (true) loop, la verifica per le modifiche periodicamente eg.every 0 , 5 secondi nel database e restituisce alcuni dati quando si verifica una modifica.

Quindi nel mio ini .py Ho creato un'app.route a/poll per JQuery da chiamare. JQuery fornisce alcune informazioni sullo stato corrente del client e la funzione poll() confronta questo con ciò che è attualmente nel database. Il ciclo termina e restituisce informazioni quando si osserva un cambiamento.

Ecco il codice Python:

@app.route('/poll') 
def poll(): 
client_state = request.args.get("state") 

    #remove html encoding + whitesapce from client state 
    html_parser = HTMLParser.HTMLParser() 
    client_state = html_parser.unescape(client_state) 
    client_state = "".join(client_state.split()) 

    #poll the database 
    while True: 
     time.sleep(0.5) 
     data = get_data() 
     json_state = to_json(data) 
     json_state = "".join(data) #remove whitespace 

     if json_state != client_state: 
      return "CHANGE" 

Il problema è che, quando il codice precedente inizia il polling, il server sembra essere sovraccaricato e altre chiamate Ajax, e altre richieste, come il caricamento di un'immagine "carico" per l'html che utilizza JQuery non risponde e non funziona.

Per l'amor di completamento Ho incluso il JQuery qui:

function poll() { 

queryString = "state="+JSON.stringify(currentState); 

$.ajax({ 
    url:"/poll", 
    data: queryString, 
    timeout: 60000, 
    success: function(data) { 
     console.log(data); 
     if(currentState == null) { 
      currentState = JSON.parse(data); 
     } 
     else { 
      console.log("A change has occurred"); 
     } 

     poll(); 

    }, 
    error: function(jqXHR, textStatus, errorThrown) { 

     console.log(jqXHR.status + "," + textStatus + ", " + errorThrown); 

     poll(); 

    } 
}); 

} 

Questo bisogno di multi-threaded o qualcosa del genere? O qualcuno ha qualche idea del perché sto vivendo questo comportamento?

Grazie in anticipo !! :)

+5

Vedere http://stackoverflow.com/questions/14814201/can-i-servi-multiple-clients-using-just-flask-app-run-as-standalone –

risposta

3

Proprio come la link @ Robᵩ menzionata, l'app per beute è solo un sovraccarico. Questo perché l'app di una fiaschetta è in modalità single-threading per impostazione predefinita quando è in esecuzione con app.run(), quindi può servire solo una richiesta alla volta.

Si può iniziare a più threading con:

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

o utilizzando un server WSGI come gunicorn o uwsgi per servire pallone con Multi Processing:

gunicorn -w 4 myapp:app 

speranze si sta godendo con Python e Flask !

+1

In generale anche se le applicazioni WSGI non sono adatte a lungo sondaggio su qualsiasi scala, anche se lo stesso vale per PHP. Questo perché sia ​​Python che l'utilizzo di WSGI e PHP sono sistemi sincroni e richiedono un processo o un thread per gestire ogni richiesta. Pertanto, per gestire un numero elevato di richieste di polling lunghe e contemporanee, è necessaria molta capacità (processi o thread). Il polling lungo è meglio implementato usando un server web e un framework asincroni. –

+0

L'alternativa se si utilizza gunicorn è utilizzare le coroutine tramite l'eventlet o gli operatori di gevent. Tuttavia, ciò pone molte restrizioni sull'applicazione, poiché è possibile utilizzare solo client per servizi di back-end e database che sono consapevoli di coroutine per evitare che possano bloccare l'intero processo. Quindi le coroutine non sono semplicemente magiche che rendono tutto buono. –

+0

@GrahamDumpleton Sì, un server asincrono vorrebbe che Tornado fosse molto meglio, e di solito è la mia prima scelta per la creazione di API o il server WebSocket. – kxxoling