2012-08-24 51 views
0

大多数服务器端脚本语言都具有exec函数(node,php,ruby等)。这允许编程语言与shell进行交互。后台进程,加载条

我希望在node.js中使用exec()来运行大型进程,这是我在浏览器中用AJAX请求做的事情。我想要一个简单的进度/加载栏来向用户显示进度。

我在下面的例子中发现了一个难题,exec函数的回调/异步特性将使这个例子花费5秒钟来加载。

我想要的是某种方式来获取浏览器的内容更新(ajax)与执行的当前状态,如加载栏。但我不希望ran文件依赖于浏览器。

有什么想法?

我的路线

exports.exec = function(req,res){ 
    // http://nodejs.org/api.html#_child_processes 
    var sys = require('sys') 
    var exec = require('child_process').exec; 
    var child; 
    child = exec("node exec/test.js", function (error, stdout, stderr) { 
    var o = { 
     "error":error, 
     "stdout":stdout, 
     "stderr":stderr, 
    }; 
    o = JSON.stringify(o); 
    res.send(o); 
    }); 
}; 

我test.js文件

var sys = require('sys'); 

var count = 0; 

var interval = setInterval(
    function(){ 
     sys.print('hello'+count); 
     count++ 

     if(count == 5){ 
      clearInterval(interval); 
     } 

    }, 
1000); 

回答

6

你应该使用socket.io这一点。 这里是一个demo app让你开始使用socket.io

你使用socket.io每发射一个事件1%,浏览器监听它并更新一个条。

你不能使用exec,你需要流式输出。
因此,你宁愿使用child_process

在服务器上。

var spawn = require('child_process').spawn, 
    exec = spawn('node exec/test.js'); 

exec.stdout.on('data', function (message) { 
    socket.emit('process', message); 
}); 

在子流程:

console.log('10%') 
// ... 
console.log('20%') 
// ... 
console.log('30%') 

如果你的子过程是一个节点的脚本,你可以这样做了很多更优雅。 您可以使用节点的cluster模块在主服务器和从服务器进程之间发送消息,而不必使用流标准输出。

我做了一个fork以前的演示应用程序添加一个路线/执行演示如何实现这一点。

当我有更多的时间我会做另一个演示程序,这是一个非常有趣和教育性的测试。感谢这个想法:D。

+0

谢谢我现在在演示中,深入socket.io文档。我很难相信没有人做到这一点。是否有可能使用其他语言? node.js和socket.io会最适合这个吗? – ThomasReggi

+0

@ThomasReggi:你可以在每个有websocket实现的语言/平台上做到这一点。做一些工作,排放和事件。做更多的工作,提交另一个事件...在每次投诉中,您都可以传递处理状态。 – davidbuzatto

+0

感谢您进一步开发您的答案。这太棒了。我很欣赏包括express3和socket.io的回购。 – ThomasReggi