下面是nodejs創(chuàng)建一個服務器的代碼。接下來我們一起分析這個過程。
var http = require('http');http.createServer(function (request, response) {  response.end('Hello World');}).listen(9297);首先我們去到lib/http.js模塊看一下這個函數的代碼。
function createServer(requestListener) { return new Server(requestListener);}只是對_http_server.js做了些封裝。我們繼續(xù)往下看。
function Server(requestListener) { if (!(this instanceof Server)) return new Server(requestListener); net.Server.call(this, { allowHalfOpen: true }); // 收到http請求時執(zhí)行的回調 if (requestListener) {  this.on('request', requestListener); } this.httpAllowHalfOpen = false; // 建立tcp連接的回調 this.on('connection', connectionListener); this.timeout = 2 * 60 * 1000; this.keepAliveTimeout = 5000; this._pendingResponseData = 0; this.maxHeadersCount = null;}util.inherits(Server, net.Server);發(fā)現_http_server.js也沒有太多邏輯,繼續(xù)看lib/net.js下的代碼。
function Server(options, connectionListener) { if (!(this instanceof Server))  return new Server(options, connectionListener); EventEmitter.call(this); // connectionListener在http.js處理過了 if (typeof options === 'function') {  connectionListener = options;  options = {};  this.on('connection', connectionListener); } else if (options == null || typeof options === 'object') {  options = options || {};  if (typeof connectionListener === 'function') {   this.on('connection', connectionListener);  } } else {  throw new errors.TypeError('ERR_INVALID_ARG_TYPE',                'options',                'Object',                options); } this._connections = 0; ...... this[async_id_symbol] = -1; this._handle = null; this._usingWorkers = false; this._workers = []; this._unref = false; this.allowHalfOpen = options.allowHalfOpen || false; this.pauseOnConnect = !!options.pauseOnConnect;}至此http.createServer就執(zhí)行結束了,我們發(fā)現這個過程還沒有涉及到很多邏輯,并且還是停留到js層面。接下來我們繼續(xù)分析listen函數的過程。該函數是net模塊提供的。我們只看關鍵的代碼。
Server.prototype.listen = function(...args) { // 處理入參,根據文檔我們知道listen可以接收好幾個參數,我們這里是只傳了端口號9297 var normalized = normalizeArgs(args); // normalized = [{port: 9297}, null]; var options = normalized[0]; var cb = normalized[1]; // 第一次listen的時候會創(chuàng)建,如果非空說明已經listen過 if (this._handle) {  throw new errors.Error('ERR_SERVER_ALREADY_LISTEN'); } ...... listenInCluster(this, null, options.port | 0, 4,           backlog, undefined, options.exclusive);}function listenInCluster() {  ...  server._listen2(address, port, addressType, backlog, fd);}_listen2 = setupListenHandle = function() {  ......  this._handle = createServerHandle(...);  this._handle.listen(backlog || 511);}function createServerHandle() {  handle = new TCP(TCPConstants.SERVER);  handle.bind(address, port);}            
新聞熱點
疑難解答
圖片精選