2016-04-23 15 views
2

データを処理するWebアプリケーションを作成しているので、FlaskでServer Sent Eventを使用しています。セッションオブジェクトがFlask stream_with_context関数内で機能しない

SSE関数にセッション変数を格納する必要がありますが、フラスコはそれを関数外には見ません。何とか修正できますか?

MWE:

server.py:

from flask import Flask, render_template, session, Response, stream_with_context 
import time 

app = Flask(__name__) 
app.secret_key = b'132d2dcf59f9604c0b48e4e3a1a1cd19a0abf121b48a4777' 

@app.route('/') 
def get_page(): 
    return render_template('progress.html') 

@app.route('/progress') 
def progress(): 
    def generate(): 
     x = 0 
     while x < 100: 
      x = x + 10 
      print(x) 
      time.sleep(0.2) 
      yield "data:" + str(x) + "\n\n" 
     session['result'] = x 
     print(session['result']) #100 
    return Response(stream_with_context(generate()), mimetype= 'text/event-stream') 

@app.route('/done') 
def done(): 
    print(session['result']) #KeyError: 'result' 
    return session['result'] 

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

progress.html:

<!DOCTYPE html> 
<html> 
<head> 
    <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"> 
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script> 
    <script> 

    var source = new EventSource("/progress"); 
    source.onmessage = function(event) { 
     $('.progress-bar').css('width', event.data+'%').attr('aria-valuenow', event.data); 
     if (event.data >=100) { 
      source.close(); 
      window.location = "http://127.0.0.1:5000/done" 
     } 
    } 
    </script> 
</head> 
<body> 
    <div class="progress" style="width: 50%; margin: 50px;"> 
     <div class="progress-bar progress-bar-striped active" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%"> 
    </div> 
</div> 
</body> 
</html> 

答えて

1

セッションはクッキーです。クッキーはヘッダーとして送信されます。残りのストリームが送信される前に、ヘッダーが最初に応答で送信されます。応答を開始した後でセッションを変更することはできません。ストリームに必要なデータをすべて送信し、受信側で処理します。

+0

ありがとう、私はこれを今理解しています。結果を 'JS'に渡し、この結果をurl引数として'/done?result = x'にリダイレクトし、 'done()'関数でセッションに格納する必要がありますか?それとももっと良い方法がありますか? – sweetSTEAM

関連する問題