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

时间:2015-10-29 14:28:33

标签: javascript node.js child-process spawn node-http-proxy

我是对应用程序进行生成(子进程)的节点应用程序, 应用程序有主机和端口:

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

5 个答案:

答案 0 :(得分:1)

您需要的是在您的代理上收听第一个响应并查看其状态代码,以确定您的应用是否成功启动。以下是您的表现方式:

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

希望这有帮助。

答案 1 :(得分:1)

不确定它是否有意义,在您的主应用程序中,体验应该从一个html页面开始,每个子进程都应该有自己的加载器。

基本上,你需要一个http Handler,它会延迟请求,直到子进程准备好。所以只需从html调用make和ajax,然后显示加载动画,直到服务准备就绪。

eval()

答案 2 :(得分:1)

我不确定我是否正确理解了这个问题,但是您想等待子进程按请求旋转,并且您希望此请求等待此子进程然后发送给它? 如果是这样,一个简单的解决方案就是使用类似这样的东西

    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()会将请求转发给子进程,getAppStatus将在子进程启动时返回200,而其他代码则不返回。一般的想法是,如果进程正在运行,则每秒都会检查,如果不是,则会在45秒后检查它是否会返回错误。等待时间和检查间隔可以很容易地调整。这有点粗糙,但是可以用于延迟请求,setTimeout将启动一个新的堆栈而不会阻塞。希望这会有所帮助。

答案 3 :(得分:1)

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

(最有可能是更智能/更复杂的解决方案,但这个解决方案最简单。)

答案 4 :(得分:1)

为什么不使用event-emitter或messenger?

@objc func didTapCommentButton(sender: UIButton) {
    var ancestor = sender.superview
    while ancestor != nil && !(ancestor! is PostCell) {
        ancestor = view.superview
    }
    guard let cell = ancestor as? PostCell,
        post = cell.post
        else { return }

    // Do something with post here
}