why request event is fired before data event in http modlues of node.js.

if we create a http server normally, the code appearance is like that:


"use strict";
let http=require('http');


let ser=http.createServer().listen(80);
ser.on('connection',(s)=>{
    let co=1;
    s.on('data',(data)=>{
        console.log('data\n');
    })


    ser.once('request',(req,res)=>{ //ser object isn't change.
        console.log('req');         //if we use the on instead of once,
        res.end('123');             // every connection emitted we will bind a request event.


    })
});

if we write some code to visit the server, we can get some Incredible things.
like this:

"use strict";
let net=require('net');
let fs = require('fs');
let socket=new net.Socket();


let opt={
    host:'127.0.0.1',
    port:80
}
socket.connect(opt,()=>{


    socket.on('data',(data)=>{
        console.log(data.toString());
        socket.end();
    });
    socket.on('error',(e)=>{
        console.log(e)
    });
    socket.on('end',(e)=>{
        console.log('end')
    });
    let html=fs.readFileSync('./a.txt');
    socket.write(html);
});

Running the server code firstly and running the request code secondly, we inspect the result from console.
It show that
req

data


The result is 'req' first and 'data' in back of that Unexpectedly.
Why?
The result should be "data req",isn't it?


Preciously, I deemed we must get data that be obtained from data event emitted before produce req object.
The Process is about this:
After getting data, we can produce the req object through combining the data parsed and part of socket that is a read stream.
So, it obviously and affirmatively show request event is later emitted than data event.

But the result confused me.
why it can appear the phenomenon.

I perplexity find the source of http module of node.js.
we should start from the function named createServer;

:( In fact,he do nothing.

const Server = exports.Server = server.Server;
exports.createServer = function(requestListener) {
  return new Server(requestListener);
};



we continue to find the object server;
the declare of server:
const server = require('_http_server');

unfortunately, we must turn to _http_server module.

function Server(requestListener) {
  if (!(this instanceof Server)) return new Server(requestListener);
  net.Server.call(this, { allowHalfOpen: true });


  if (requestListener) {
    this.addListener('request', requestListener);
  }


  /* eslint-disable max-len */
  // Similar option to this. Too lazy to write my own docs.
  // http://www.squid-cache.org/Doc/config/half_closed_clients/
  // http://wiki.squid-cache.org/SquidFaq/InnerWorkings#What_is_a_half-closed_filedescriptor.3F
  /* eslint-enable max-len */
  this.httpAllowHalfOpen = false;


  this.addListener('connection', connectionListener);


  this.timeout = 2 * 60 * 1000;


  this._pendingResponseData = 0;
}
util.inherits(Server, net.Server);

the function tell us the http server is inherited to net.Server.

Now, we find there is no function to be invoked, but there is a event--connection.
Following the clues, we find a connectionListener function.

It too large to be read. :( 261~548
function connectionListener(socket){...}
It seems like connection events listener of net.server.

To fire the request event, It must exit emit('request',req,res);
so, we can find that for a start;
column 528~533

if (self.listenerCount('checkContinue') > 0) {
  self.emit('checkContinue', req, res);
} else {
  res.writeContinue();
  self.emit('request', req, res);
}

the structure of function:
267~295 the declare of function
296~353 statements
354~459 the callback of socket
460~547 function

it belongs to function 460~547 function parserOnIncoming(req, shouldKeepAlive){..}
According to the function name, we can know the function will be invoked in the Incoming of parser.
what's Parser?
search the key of parse-->
we find
316 var parser = parsers.alloc();
332 parser.onIncoming = parserOnIncoming;
363~369

function socketOnData(d) {
  assert(!socket._paused);
  debug('SERVER socketOnData %d', d.length);
  var ret = parser.execute(d);


  onParserExecuteCommon(ret, d);
}

we find the column 334-->socket.on('data', socketOnData);

the function of parser.execute is in socketOndata,It is very reasonable.
so I can infer like that:

"use strict"


let event=require('events').EventEmitter;
let un=require('util');
function a(){}

un.inherits(a,event);
let c=new a();

c.on('data',()=>{
	console.log(`1 data`);
	c.emit('request');
});


c.on('data',()=>{
	console.log(`2,data`);
});


c.on('request',()=>{
<span style="white-space:pre">	</span>console.log(`1 request`);
});


c.emit('data');

the result is:
1 data
1 request
2,data

I test many times, the result is stable.

but when parserOnIncoming will be invoked actually?
we find the parsers is from _http_common module.

we find 'parser.onIncoming(parser.incoming, shouldKeepAlive);'' in function parserOnHeadersComplete.
and  when parserOnHeadersComplete will be invoked?
we just find parser[kOnHeadersComplete] = parserOnHeadersComplete;
because the HTTPParser is written in c we can't read, 
so we only can infer from function name that it will be invoked amid the process of parse happened.
and the parser will be execute in the callback of data event to socket.

the origin of req object is come from one of parameter of  function parserOnIncoming.
In that we find the statement-
'skipBody = parser.onIncoming(parser.incoming, shouldKeepAlive);'
'  parser.incoming = new IncomingMessage(parser.socket);'

so the req object is a instance of IncomingMessage;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Japan has been hunting whales for centuries, but in recent years, the practice has come under scrutiny from the international community. Many countries and conservationists argue that Japan should stop hunting whales altogether, as it is both cruel and unnecessary. In this essay, we will explore why Japan should stop hunting whales. First and foremost, hunting whales is cruel. The methods used to hunt whales are often inhumane and cause significant suffering to the animals. Whales are generally hunted using harpoons, which are fired into their bodies, causing immense pain and trauma. They may take hours or even days to die, during which time they may suffer from dehydration, exhaustion, and stress. Additionally, the stress caused by hunting can have long-lasting effects on whale populations, including decreased reproduction rates and increased mortality. Secondly, hunting whales is unnecessary. While some argue that whaling is an important cultural tradition in Japan, the reality is that most Japanese people do not consume whale meat. In fact, the demand for whale meat has been steadily declining in Japan for decades. Furthermore, there are plenty of alternative sources of protein available, making the practice of hunting whales unnecessary from a dietary standpoint. Thirdly, hunting whales is unsustainable. Many whale populations are already in decline due to overfishing and other environmental factors. Continued hunting of whales will only exacerbate this problem and could lead to the extinction of certain species. This would be a significant loss for the natural world and could have far-reaching consequences for marine ecosystems. Finally, Japan's continued hunting of whales is a violation of international law. In 1986, the International Whaling Commission (IWC) announced a moratorium on commercial whaling, which Japan has repeatedly violated. While Japan claims that its whaling activities are for scientific research purposes, many countries and conservationists argue that this is simply a cover for commercial whaling. Japan's whaling activities have been met with international condemnation, and continued hunting of whales could damage Japan's reputation on the global stage. In conclusion, Japan should stop hunting whales. The practice is cruel, unnecessary, unsustainable, and a violation of international law. While some argue that whaling is an important cultural tradition, the reality is that it is a dying practice that is no longer needed. By ending its whaling activities, Japan could demonstrate its commitment to animal welfare, sustainability, and international law, while also contributing to the conservation of whale populations around the world.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值