Node.js将数据从终端命令传输到客户端

时间:2014-02-02 00:14:00

标签: node.js

这里已经有一些关于node.js执行命令和输出数据的问题,但我仍然无法解决这个问题。我想要的是使用node.js我想执行一个运行很长时间的python脚本并产生一些中间输出。我想在生成后立即将这些输出流式传输到客户端。我尝试了以下内容,但我得到的是,只有在命令完成后才能获得整个输出。如何让它实时将数据传递到套接字?感谢。

function run_cmd(cmd, args) {
  var spawn = require('child_process').spawn,
  child = spawn(cmd, args);
  return child;
}

io.sockets.on('connection', function (socket) {
  var foo = new run_cmd('python', ['test.py']);
  foo.stdout.setEncoding('utf-8');
  foo.stdout.on('data', function(data) {
     console.log('sending data');
     io.sockets.emit('terminal', {output: data});;
  });
);

1 个答案:

答案 0 :(得分:6)

你所有的node.js代码都没问题。你的代码只发送一次数据,因为你的代码只获取一次数据。

关键是put或print命令不足以触发foo.stdout.on 尝试在要在ruby代码中发送块的位置添加'$ stdout.flush'。 您需要明确订购输出数据。

这是我的测试代码。

JS

var spawn = require('child_process').spawn;
var cmd  = spawn('ruby', ['testRuby.rb']);
var counter = 0;
cmd.stdout.on('data', function(data) {
    counter ++;
  console.log('stdout: ' + data);
});

cmd.stderr.on('data', function(data) {
  console.log('stderr: ' + data);
});

cmd.on('exit', function(code) {
  console.log('exit code: ' + code);
  console.log(counter);
});

testRuby.rb

def execute_each_sec(sleep_sec)
  yield
  sleep sleep_sec
end

5.times do
  execute_each_sec(1) do ||
    puts "CurrentTime:#{Time.now}"
    $stdout.flush
  end
end

你可以看到我正在调用$ stdout.flush来在testRuby.rb中显式输出数据。 如果我删除它,node.js将不会得到任何东西,直到testRuby.rb的执行完成。

<强>编辑 大声笑我的坏。我使用ruby而不是python。 在python的情况下,使用sys.stdout.flush(),如svkk所说

修改 在python中,您还可以使用-u标志强制它在每次打印后刷新。