没有收到来自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()); });