没有收到来自nodejs派生进程的stdout

我试图让nodejs冒险 (一种基于文本的旧游戏)进行交互。 这个想法是将冒险作为一个subprocess打开,然后通过写入stdin并在stdout上放置一个事件监听器来玩游戏。

当游戏开始时,它打印一个初始的:

欢迎来到冒险! 你想要说明吗?

所以为了说明我的问题,我有一个nodejs + express实例:

 var childProcess = require('child_process'); var spawn = childProcess.spawn; var child = spawn('adventure'); console.log("spawned: " + child.pid); child.stdout.on('data', function(data) { console.log("Child data: " + data); }); child.on('error', function () { console.log("Failed to start child."); }); child.on('close', function (code) { console.log('Child process exited with code ' + code); }); child.stdout.on('end', function () { console.log('Finished collecting data chunks.'); }); 

但是当我启动服务器时,游戏中的文本不会到达事件监听器:

 spawned: 24250 

这就是我得到的所有输出。 child.stdout.on甚至是监听器都不会被调用。 为什么不是从游戏的最初线被拾起?

如果我将以下代码行添加到上面的JavaScript块中,则程序输出会立即显示。 所以adventure运行,我现在可以强制它触发child.stdout.on事件监听器…但是这也结束了subprocess,这将失败的阅读和写作的目的。

 ... child.stdout.on('end', function () { console.log('Finished collecting data chunks.'); }); child.stdin.end(); 

现在输出结果是:

 spawned: 28778 Child data: Welcome to Adventure!! Would you like instructions? user closed input stream, quitting... Finished collecting data chunks. Child process exited with code 0 

我敢肯定,对我来说这是一个微不足道的疏忽,我很欣赏任何帮助。

在经过了几次Nodejs文档之后,我确信自己或者丢失了一些相当大的东西,或者spawn命令无法正常工作。 所以我创build了一个github问题 。

答案立即发布:如果你想快速访问,subprocess不能缓冲输出。

所以要实现我最初的目标:

 var childProcess = require('child_process'); var spawn = childProcess.spawn; var child = spawn('unbuffer', 'adventure'); console.log("spawned: " + child.pid); child.stdout.on('data', function(data) { console.log("Child data: " + data); }); child.on('error', function () { console.log("Failed to start child."); }); child.on('close', function (code) { console.log('Child process exited with code ' + code); }); child.stdout.on('end', function () { console.log('Finished collecting data chunks.'); }); 

function区别在于使用非缓冲区,一个禁用输出缓冲的命令。

传递的data是一个缓冲区types,而不是一个string。 因此,您需要一个解码器来读取该缓冲区,然后执行日志logging。

以下是如何做到这一点。

 var StringDecoder = require('string_decoder').StringDecoder; var decoder = new StringDecoder('utf8'); child.stdout.on('data', function (data) { var message = decoder.write(data); console.log(message.trim()); });