2016-06-03 15 views
0

Ich habe eine Knoten/Express-Anwendung, die ein externes Programm aufruft und die Ausgabe erfassen und verschiedene mögliche Zustände verarbeiten muss.Sitzungsvariablen können nicht von untergeordneten Prozessrückrufen festgelegt werden.

Das Problem ist: Ich kann den Sitzungsstatus nicht innerhalb des Rückrufs (Daten) festlegen.

Die Funktion der Anrufverarbeitung ist:

app.get('/test/:script', function(req, res) { 
    if (req.session.state != SessionState.STARTED) { 
     req.session.state = SessionState.STARTED; 
     req.session.scriptname = req.params.script; 
     req.session.outputText = ''; 

     var test = spawn('./Test', [ req.session.scriptname ]); 

     test.stdout.on('data', function(data) { console.log('+++' + JSON.stringify(req.session)); req.session.outputText += data.toString() + '<br/>'; }); 
     test.on('close', function(code) { console.log('---' + JSON.stringify(req.session)); console.log(code); req.session.state = SessionState.FINISHED; }); 
    } 

    res.redirect(301, '/'); 
}) 

Und die Standardroute ist:

app.get('/', function (req, res) { 
    var responseBody = ''; 
    var responseHead = ''; 
    switch (req.session.state) { 
     case undefined: 
     case SessionState.IDLE: 
     var files = fs.readdirSync('../input') 
     for (var i = 0; i < files.length; i++) { 
      var fname = files[i]; 
      responseBody += '<a href="/test/' + fname + '">' + fname + '</a> <br/>'; 
     } 
     req.session.state = SessionState.IDLE; 
     break; 

     case SessionState.STARTED: 
     responseHead += '<meta http-equiv="refresh" content="2">'; 
     responseBody += req.session.outputText; 
     console.log('***' + JSON.stringify(req.session)); 
     break; 

     case SessionState.FINISHED: 
     responseBody += 'Execution finished'; 
     break; 
    } 

    var responseText = '<html>' + 
     '<head>' + responseHead + '</head>' + 
     '<body>' + responseBody + '</body>' + 
     '</html>' 

    res.send(responseText); 
}) 

Die Konsolenprotokoll zeigt ganz andere Objekte: ein durch die erste Funktion aktualisiert und enthält die Voll Ausgabe meines Programms, aber das andere Objekt (von der zweiten Funktion protokolliert) ändert sich nie.

Wie stelle ich sicher, dass ich immer auf das gleiche Sitzungsobjekt zugreife? Wenn ich der Konsolenausgabe req.sessionID hinzufüge, ist der Wert immer gleich.

Antwort

1

Ich bin nicht sicher, welche console.logs Sie meinen (es gibt ein paar da), aber eine mögliche Ursache für Ihre Probleme ist, dass die Weiterleitung ausgegeben wird, bevor der Kindprozess abgeschlossen ist.

Hier ist eine mögliche Rewrite:

app.get('/test/:script', function(req, res) { 
    if (req.session.state != SessionState.STARTED) { 
    req.session.state = SessionState.STARTED; 
    req.session.scriptname = req.params.script; 
    req.session.outputText = ''; 

    var test = spawn('./Test', [ req.session.scriptname ]); 

    test.stdout.on('data', function(data) { 
     console.log('+++' + JSON.stringify(req.session)); 
     req.session.outputText += data.toString() + '<br/>'; 
    }); 
    test.on('close', function(code) { 
     console.log('---' + JSON.stringify(req.session)); 
     console.log(code); 
     req.session.state = SessionState.FINISHED; 
     res.redirect(301, '/'); 
    }); 
    } else { 
    res.redirect(301, '/'); 
    } 
}) 
+0

Der Prozess seit einiger Zeit läuft, und ich möchte einen Prozess Polling für Teilergebnisse haben. –

+1

Okay, fair genug. Ich denke, der Standard für "Express-Session" ist, dass Sitzungen am Ende einer Antwort gespeichert werden, was in Ihrem Fall die Weiterleitung sein wird. Wenn Sie das Polling implementieren möchten, müssen Sie verhindern, dass die Sitzung automatisch gespeichert wird. Ich bin mir aber nicht sicher, wie ich das machen soll :( – robertklep

Verwandte Themen