如何在Node中关闭stdin?

时间:2018-02-22 18:47:17

标签: node.js node-streams

我正在学习Node.js并且认为我有一个非常简单的脚本,但是没有任何关于调整的东西会让我的脚本永远挂起。

说我运行了一个哑服务器:

$ nc -l 32001 <<EOF
HTTP/1.1 200 OK
Content-Type: text/plain

Works
EOF

我运行以下脚本:

var http = require('http');
var options = {
  hostname: 'localhost',
  port: 32001,
  method: 'POST',
  headers: {'Content-Type': 'text/plain'}
};
var req = http.request(options, res => {
  var exitCode = res.statusCode >= 200 && res.statusCode < 300 ? 0 : 1;
  res.pipe(process.stdout).on('end', () => process.exit(exitCode));
});
req.on('error', error => console.error(error));
process.stdin.pipe(req)
  .on('end', () => console.log('this does trigger'));

但是当我执行以下操作时:

$ echo foobar | node my-script.js

它只是挂起并且永远不会到达请求回调。我希望req流结束并调用http.request回调,然后输出Works并最终退出进程。

我检查end事件确实是从process.stdin.pipe()调用的,我试图在req回调中手动结束end流。但它不会结束。如何将stdin管道传输到http.request并仍然让它结束流?

1 个答案:

答案 0 :(得分:3)

你走在正确的轨道上;你只需要将你的听众附加到正确的对象事件。在第一种情况下(如编写,而不是执行):

res.pipe(process.stdout).on('end', () => process.exit(exitCode));

你说的是:“将数据从响应传递到stdout,当 stdout 结束时,退出进程。”

你的意思是:“将数据从响应传递到stdout。当响应结束时,退出进程。”编纂:

res.pipe(process.stdout);
res.on('end', () => process.exit(exitCode));

此处的清晰点是,除非您专门关闭process.stdout,否则在您退出程序之前,永远不会关闭/结束。但是,response将在HTTP交互完成时结束。

第二种情况类似:

process.stdin.pipe(req)
  .on('end', () => console.log('this does trigger'));

你说的是:“将数据从stdin传输到请求,当请求结束时,写一条消息。”

你的意思是:“将数据从stdin传送到请求。当 stdin 结束时,写一条消息。”编纂:

process.stdin.pipe(req);
process.stdin.on('end', () => console.log('this does trigger'));

这里稍微有些细微之处,因为您可以监听 stdin end事件或请求finish事件:< / p>

process.stdin.pipe(req).on('finish', () => console.log('Request has finished writing/sending');
process.stdin.on('end', () => console.log('Stdin has no more data'));

为了完整性,那么,您的工作客户会回复您,并根据假设的教学清晰度进行一些温和的文本修改:

var http = require('http');
var options = {
  hostname: 'localhost',
  port: 32001,
  method: 'POST',
  headers: {'Content-Type': 'text/plain'}
};
var req = http.request(options, res => {
  var exitCode = res.statusCode >= 200 && res.statusCode < 300 ? 0 : 1;
  res.pipe(process.stdout);
  res.on('end', () => {
    console.log('Response (IncomingMessage) has no more data; exiting with code:', exitCode);
    process.exit(exitCode);
  });
});
req.on('error', error => console.error(error));
process.stdin.on('end', () => console.log('Stdin has no more data.'));
process.stdin.pipe(req).on('finish', () => console.log('Request has finished writing/sending'));

命令行输出:

$ echo Some text from stdin | node test.js; echo $?
Stdin has no more data.
Request has finished writing/sending
Works
Response (IncomingMessage) has no more data; exiting with code: 0
0

在“服务器”:

$ nc -l 32001 <<EOF
HTTP/1.1 200 OK
Content-Type: text/plain

Works
EOF
POST / HTTP/1.1
Content-Type: text/plain
Host: localhost:32001
Connection: close
Transfer-Encoding: chunked

15
Some text from stdin

0