why request event is fired before data event in http modlues of node.js.
来源:互联网 发布:广州java语言培训机构 编辑:程序博客网 时间:2024/06/06 19:04
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
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
- why request event is fired before data event in http modlues of node.js.
- Event in node
- node.js的event loop
- Getting the ID of the element that fired an event using jQuery
- 【Redis】Why is an Event Library needed at all?
- Adding timeout support for http request in Node.JS
- Using HTTP Proxy in Node.js with request package
- Understanding the node.js event loop
- Understanding the node.js event loop
- Understanding the node.js event loop
- Understanding the node.js event loop
- Understanding the node.js event loop
- Node.js Event-loop事件循环
- node.js中Event loop机制
- An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means
- Understanding the Node.js Event Loop - Node.js at Scale
- GetInvocationList of an event in VB.NET
- The GridView 'GridViewID' fired event PageIndexChanging which wasn't handled.
- Base64编码与URL编码的不同
- c++对内存的浅谈以及内存泄漏问题的探讨之二
- C/C++复习:数组作实参,指针作形参排序
- Android 停止调试程序
- C#通过托管调用Win32 api获取键盘状态
- why request event is fired before data event in http modlues of node.js.
- 打开EXCEL的时候总是自动弹出VS2008的安装程序解决办法
- git 分支合并时如何忽略某个文件
- iOS开发 ☞ KVC详解
- 通过java反射机制获取该类的所有属性类型、值、
- 《算法导论》笔记(一)
- jdbc远程连接hiveserver2
- 详解RecyclerView+BGARefreshLayout实现自定义下拉刷新、上拉加载和侧滑删除效果
- CentOS7->lamp