如何将子进程的无缓冲输出传递给HTTP.ServerResponse?
下面的Node.js代码适用于缓冲输出,但不适用于无缓冲输出。
var http = require('http'),
spawn = require('child_process').spawn;
http.createServer(function (req, res) {
req.on('data', function (data) {
var ping = spawn("ping", ["127.0.0.1"]);
ping.stdout.pipe(res);
ping.stderr.pipe(res);
req.connection.on('end', function() {
ping.kill();
});
});
});
以下是ping 127.0.0.1
的输出:
ping 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
由于ping
将请求超时作为无缓冲数据写入STDOUT,因此上述代码仅在ping
成功时才有效。
我正在使用Node.js v0.8.19。
答案 0 :(得分:5)
这是common problem,不一定限于Node.js。
如果您使用的是Unix,则可以使用unbuffer
脚本,该脚本是Expect的一部分。大多数GNU系统还提供stdbuf
,这可以让你做同样的事情(尽管我不太熟悉它)。
如果您想使用unbuffer
,只需将上面的示例更改为:
var ping = spawn("unbuffer", ["ping", "127.0.0.1"]);
如果您使用的是Windows,则事情要困难得多,因为Windows本身并不提供与PTY
等效的任何等价物。诸如winpty(及其JavaScript绑定,pty.js)等项目尝试使用Windows Console API重新创建此功能,尽管我发现它们的实现有些错误和不完整。< / p>
ActiveState's win32 Expect package不是最容易安装的东西,并且在默认发行版中不包含unbuffer
脚本。但是,如果您设法使所有工作正常并对Unix unbuffer
脚本进行一些小的修改,您应该能够编译unbuffer
可执行文件,然后可以从Node调用。
答案 1 :(得分:0)
您正在请求连接端终止ping进程,这会在服务器上成功收到请求后立即发生。 ping在输出Request timeout for icmp_seq 5
之前会一直关闭。
尝试做这样的事情
var http=require('http');
var spawn = require('child_process').spawn;
http.createServer(function (req, res) {
var ping = spawn("ping", ["127.0.0.1","-c","20"]);
ping.stdout.pipe(res);
ping.stderr.pipe(res);
}).listen(8080);
注意: ping继续下去,所以你不能等待它结束。使用-c ping x次。