下面是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);}
新聞熱點
疑難解答
圖片精選