节点js从不同的进程获取和设置数据

我已经完成了产生(subprocess)的节点应用程序和应用程序,应用程序有主机和端口:

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); }); 

一些应用程序将立即开始,一些应用程序将需要一些时间10 – 20秒,直到他们开始

现在我使用节点http代理来运行应用程序,问题是,当使用希望在运行之前运行应用程序,我得到错误。 任何想法如何以某种方式我可以解决这个问题?

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

顺便说一下,由于我们的框架限制,我不能发送代理错误的响应500。 任何其他的想法如何跟踪应用程序也许有一些超时,以查看它发送的响应200天气。

更新 – 我的逻辑样本

 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'); }); } 

您需要的是听取代理的第一个响应,并查看其状态代码以确定您的应用是否成功启动。 以下是你如何做到这一点:

 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; }); 

希望这可以帮助。

不知道是否有意义,在您的主要应用程序的经验应该开始一个HTML页面,每个subprocess应该有自己的加载程序。

所以基本上,你需要一个HTTP处理程序,它将延迟请求,直到subprocess准备就绪。 所以只需从html中调用和ajax调用,并显示加载animation,直到服务准备就绪。

 //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); }); }) 

我不知道我是否正确地理解了这个问题,但是您希望等待subprocess根据请求旋转,并且您希望此请求等待此subprocess,然后发送给它? 如果这是一个简单的解决scheme将是使用这样的东西

  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!')); } } ); 

函数continueWithRequest()将把请求转发给subprocess,getAppStatus将在subprocess启动时返回200,否则返回一些其他代码。 一般的想法是,虽然将检查每一秒,如果进程正在运行,45秒后,如果没有,它会返回一个错误。 等待时间和检查间隔可以很容易地调整。 这有点粗糙,但会延迟请求,setTimeout将启动一个新的堆栈,不会阻塞。 希望这可以帮助。

如果您知道应用程序启动和运行需要多长时间,只需添加setTimeout(proxyRequest, <Time it takes the app to start in MS>)

(最有可能更聪明/复杂的解决scheme,但这是最简单的。)

为什么不使用事件发射器或信使?

 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); }) }