通过expressjs将子stream程的stdoutstream到浏览器

我们有一个使用nodejsexpresschild_process.spawn构build的应用程序。 一个要求就是我们需要在运行时产生一个进程并捕获它的输出并将其呈现给用户。

我们有这个工作。 但是,我们需要找出一种方法来stream式输出,而不是等待subprocess存在。

我们环顾四周,找不到任何明确的例子,并想知道这里有人有什么想法吗?

一切正在工作。 我们只是不关心在显示整个输出之前不得不等待命令完成的用户体验。 如果我们可以对它进行stream式处理,那么当stdout数据事件被触发时,这将是理想的,浏览器将使用新数据进行更新。 就目前而言,它确实是大块的,而不是一个大的块。所以它很适合做这个。

Express路由的响应对象也是可写入stream的一个实例,因此您可以将subprocess的stdiostream传stdio响应。

 app.get('/path', function(req, res) { var child = spawn('ls', ['-al']); child.stdout.pipe(res); }); 

另一种方法是使用Socket.IO 。 Socket.IO被devise用于客户端和服务器之间的这种基于事件的实时通信。

关键是在写入之后刷新标准输出stream。 这应该触发“childprocess.stdout.on('data',…)”事件。

怎么做取决于你的subprocess是用什么语言编写的。假设你正在运行一个python脚本并使用“print”写入标准输出,那么你需要这样做:

 import sys # Flush after each print to stdout sys.stdout.flush() 

这里有一个简单的例子,它实现了你使用Socket.IO所要求的东西。 服务器端代码:

 var app = require('express')(); var http = require('http').Server(app); var io = require('socket.io')(http); var child = require('child_process'); app.get('/', function(req, res){ res.sendFile(__dirname + '/index.html'); }); http.listen(8000, function(){ console.log('listening on *:8000'); }); io.on('connection', function(socket){ console.log('new user connected'); var python = child.spawn( 'python', ['compute.py'],[]); var chunk = ''; python.stdout.on('data', function(data){ chunk += data socket.emit('newdata', chunk); } ); python.stderr.on('data', function (data) { console.log('Failed to start child process.'); }) })