如何将无缓冲的数据从STDOUT传输到ServerResponse?

时间:2013-04-01 22:37:31

标签: node.js

如何将子进程的无缓冲输出传递给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。

2 个答案:

答案 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次。