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

Lak*_*aky 5 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});;
  });
);
Run Code Online (Sandbox Code Playgroud)

sui*_*ish 7

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

关键是put或print命令不足以触发foo.stdout.on尝试在你要在ruby代码中发送chunk的点添加'$ 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);
});
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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

编辑 哈哈,我的坏.我使用ruby而不是python.在python的情况下,使用sys.stdout.flush(),如svkk所说

编辑: 在python中你也可以使用-uflag强制它在每次打印后刷新.