2015-10-29 4 views
28

I Knoten-Anwendung haben, die (Child-Prozess) laichen getan und Anwendung, die Anwendung haben Host und Port:Knoten js get und set Daten aus verschiedenen Prozess

var exec = require('child_process').spawn; 
var child = exec('start app'); 
console.log("Child Proc ID " + child.pid) 
child.stdout.on('data', function(data) { 
    console.log('stdout: ' + data); 
}); 
child.stderr.on('data', function(data) { 
    console.log('stdout: ' + data); 
}); 
child.on('close', function(code) { 
    console.log('closing code: ' + code); 
}); 

einige Anwendung wird sofort beginnen und einige Anwendung dauert einige Zeit 10 - 20 Sekunden, bis sie beginnen.

Jetzt benutze ich den Knoten http-Proxy, um die App zu starten, und das Problem ist, dass ich Fehler bekomme, wenn die Anwendung die App vor dem Start ausführen möchte. Irgendeine Idee, wie ich dieses Problem irgendwie lösen kann?

proxy.on('error', function (err, req, res) { 
    res.end('Cannot run app'); 
}); 

Btw, ich kann keine Antwort 500 in Proxy-Fehler aufgrund der Beschränkung unseres Frameworks senden. Jede andere Vorstellung davon, wie kann ich die Anwendung verfolgen vielleicht mit einer gewissen Timeout Wetter zu sehen, es Antwort 200.

UPDATE senden - Abgebildete meiner Logik

httpProxy = require('http-proxy'); 
var proxy = httpProxy.createProxyServer({}); 
http.createServer(function (req, res) { 
    console.log("App proxy new port is: " + 5000) 
    res.end("Request received on " + 5000); 
}).listen(5000); 

function proxyRequest(req, res) { 
    var hostname = req.headers.host.split(":")[0]; 
    proxy.web(req, res, { 
     target: 'http://' + hostname + ':' + 5000 
    }); 

    proxy.on('error', function (err, req, res) { 
     res.end('Cannot run app'); 
    }); 
} 
+0

Sie erwähnen, dass Sie Rahmenbeschränkungen haben - können Sie ins Detail gehen? Es ist schwer zu wissen, welche Lösungen Ihnen zur Verfügung stehen, wenn wir nicht wissen, was wir können und was nicht.Haben Sie die Kontrolle über den oder die gerade entstehenden Kindprozesse? –

+0

Was erwarten Sie, wenn eine Anfrage gesendet wurde und die App noch nicht verfügbar ist? – Koder

Antwort

1

Was Sie brauchen, ist für die erste Antwort zu hören auf Proxy und schauen Sie sich seinen Statuscode an, um festzustellen, ob Ihre App erfolgreich gestartet wurde oder nicht. Hier ist, wie Sie das tun:

proxy.on('proxyRes', function (proxyRes, req, res) { 
    // Your target app is definitely up and running now because it just sent a response; 
    // Use the status code now to determine whether the app started successfully or not 
    var status = res.statusCode; 
}); 

Ich hoffe, dies hilft.

+0

Danke, aber wann und wie soll ich das machen? Angenommen, ich lege deinen Code ein und der Nutzer klickt auf den Browser, um die App zu starten, die noch nicht da ist, also erst sieht er den Fehler, also wie kann ich das überwinden? vielleicht bist du ein Experte in diesem Thema und ich vermisse etwas hier :) Danke! –

+0

Wenn also der Benutzer den Browser öffnet und der Browser eine Anfrage an Ihre App sendet, sollte der Proxy das Ereignis 'proxyRes' ausgeben. Wenn Ihre App nicht bereit ist, erhält der Browser erst dann eine Antwort. Also ich denke, das sollte funktionieren. – idancali

+0

Danke, aber der Fehler wird vorher nicht kommen? –

1

Nicht sicher, ob es Sinn macht, in Ihrer Hauptanwendung sollte die Erfahrung mit einer HTML-Seite beginnen und jeder Kindprozess sollte eigenen Lader haben.

Also im Grunde benötigen Sie einen http-Handler, der die Anfrage verweilt, bis der Kindprozess fertig ist. Also einfach make und ajax aus dem html heraus aufrufen und Lade-Animation anzeigen, bis der Service fertig ist.

//Ajax call for each process and update the UI accordingly 
$.get('/services/status/100').then(function(resp) { 
    $('#service-100').html(resp.responseText); 
}) 

//server side code (express syntax) 
app.get('/services/status/:id ', function(req,res) { 
    // Check if service is ready 
    serviceManager.isReady(req.params.id, function(err, serviceStats) { 
     if(err) { 
      //do logic err here , maybe notify the ui if an error occurred 
      res.send(err); 
      return; 
     } 
     // notify the ui , that the service is ready to run , and hide loader 
     res.send(serviceStats); 
    }); 
}) 
1

Ich bin nicht sicher, ob ich die Frage richtig verstanden hat, aber Sie wollen warten, ein Kind-Prozess auf Anfrage zu drehen, und Sie wollen, dass diese Anfrage für dieses Kind Prozess zu warten, und dann schicken Sie es sein? Wenn dem so ist eine einfache Lösung sein, etwas zu verwenden, wie dieses

var count = 0;//Counter to check 
    var maxDelay = 45;//In Seconds 
    var checkEverySeconds = 1;//In seconds 
    async.whilst(
     function() { 
      return count < maxDelay; 
     }, 
     function (callback) { 
      count++; 
      self.getAppStatus(apiKey, function (err, status) { 
       if (status != 200) { 
        return setTimeout(callback, checkEverySeconds * 1000); 

       } 
       continueWithRequest(); 

      }); 
     }, 
     function (err) { 
      if (err) { 
       return continueWithRequest(new Error('process cannot spin!')); 
      } 
     } 
    ); 

Die Funktion continueWithRequest() wird die Anforderung an den Kindprozess weiterzuleiten und die getAppStatus wird 200 zurück, wenn der Kindprozess hat begonnen und einige andere Code, wenn es nicht ist. Die allgemeine Idee ist, dass während jede Sekunde überprüft wird, ob der Prozess läuft und nach 45 Sekunden, wenn nicht, wird es einen Fehler zurückgeben. Wartezeit und Prüfintervalle können einfach angepasst werden. Dies ist ein bisschen grob, aber wird für die Verzögerung der Anfrage funktionieren und setTimeout wird einen neuen Stapel starten und nicht blockieren. Hoffe das hilft.

1

Wenn Sie wissen (um), wie viel Zeit die App aufstehen und laufen dauert, fügen Sie einfach setTimeout(proxyRequest, <Time it takes the app to start in MS>)

(Es gibt wahrscheinlich mehr smart/komplizierte Lösungen, aber dieses ist die einfachste.)

1

Warum nicht Event-Emitter oder Messenger verwenden?

var eventEmitter = require('event-emitter') 
var childStart = require('./someChildProcess').start() 

if (childStart !== true) { 
     eventEmitter.emit('progNotRun', { 
      data: data 
     }) 
} 

function proxyRequest(req, res) { 

    var hostname = req.headers.host.split(":")[0]; 
    proxy.web(req, res, { 
     target: 'http://' + hostname + ':' + 5000 
    }); 

    eventEmitter.on('progNotRun', function(data) { 
     res.end('Cannot run app', data); 
    }) 
} 
Verwandte Themen