未设置“基于数据”事件侦听器时,nodejs http模块将做什么?

时间:2019-01-25 06:49:39

标签: node.js http tcp

'use strict';

const http = require('http');
const fs = require('fs');

http.createServer((req, res) => {
  (async () => {
    await (new Promise((resolve, reject) => setTimeout(resolve, 10000)));
    console.log('recv...');
    req.setEncoding('utf8');
    req.on('data', (chunk) => {
      fs.writeFileSync('test.txt', chunk, { flag: 'a' });
    });
    req.on('end', () => {
      res.end();
    });
  })();
}).listen(23380, '0.0.0.0');

当未设置“基于数据”事件侦听器时,nodejs http模块(或通常的http协议)会做什么?

扔掉包裹(会丢掉包裹)吗?

还是将软件包存储在内存中(它会消耗掉我所有的内存)吗?

还是告诉客户“嘿,我不要你的包裹。待会儿再寄给我”?

它如何工作?

如果能提供一些参考(源代码或文档),我将不胜感激。

2 个答案:

答案 0 :(得分:0)

http.createServer实际提供的是一个EventEmitter Source。因此,您的问题可以简化为询问未监听事件发生了什么。

对于事件,无论满足条件的事件发生时,谁听该事件都是如此。因此,如果“数据” 事件由http.createServer提供的EventEmitter发出,则无法通过不列出事件来停止它。您实际上所做的只是忽略它。

当您监听 data 对象时,您实际上在做的是使用 req向该特定对象(Source)的监听器数组中添加一个新的监听器。 操作。因此,如果您尚未订阅该事件,那么它将不会被发送给您。它如何影响代码取决于代码是否可以在没有事件的情况下完成。

答案 1 :(得分:0)

一个下午阅读完源代码后,我想找到了问题的答案。

http服务器将首先接收数据。

但是,当数据池中的数据到达水印行时,它将暂停套接字,如https://github.com/nodejs/node/blob/master/lib/_http_server.js:366所说,并且代码位于https://github.com/nodejs/node/blob/master/lib/_http_server.js:636。

暂停套接字意味着服务器将告诉客户端“不要向我发送更多数据”。我在Wireshark中发现“ tcp窗口已满”,我认为是由于暂停而由服务器发送的。

暂停套接字还意味着它将不会使内存爆炸,并且也不会不会丢失数据。 (数据仍存储在客户端中

在设置事件侦听器时,将恢复流。代码位于https://github.com/nodejs/node/blob/master/lib/_stream_readable.js:826。

处理继续。