## http
### server:
http.createServer是為了創建 Node 服務,比如 Koa 服務框架就是基于 http.createServer 封裝的。
[https://juejin.im/post/5a31d2276fb9a0452207839c](https://juejin.im/post/5a31d2276fb9a0452207839c)
http.IncomingMessage是HTTP請求的信息,是后端開發者最關注的內容,一般由http.Server的request事件發送,并作為第一個參數傳遞,包含三個事件
* data:當請求體數據到來時,該事件被觸發,該事件提供一個參數chunk,表示接受的數據,如果該事件沒有被監聽,則請求體會被拋棄,該事件可能會被調用多次(這與nodejs是異步的有關系)
* end:當請求體數據傳輸完畢時,該事件會被觸發,此后不會再有數據
* close:用戶當前請求結束時,該事件被觸發,不同于end,如果用戶強制終止了傳輸,也是用close
http.ServerResponse是返回給客戶端的信息,決定了用戶最終看到的內容,一般也由http.Server的request事件發送,并作為第二個參數傳遞,它有三個重要的成員函數,用于返回響應頭、響應內容以及結束請求
* res.writeHead(statusCode,\[heasers\]):向請求的客戶端發送響應頭,該函數在一個請求中最多調用一次,如果不調用,則會自動生成一個響應頭
* res.write(data,\[encoding\]):想請求的客戶端發送相應內容,data是一個buffer或者字符串,如果data是字符串,則需要制定編碼方式,默認為utf-8,在res.end調用之前可以多次調用
* res.end(\[data\],\[encoding\]):結束響應,告知客戶端所有發送已經結束,當所有要返回的內容發送完畢時,該函數必需被調用一次,兩個可選參數與res.write()相同。如果不調用這個函數,客戶端將用于處于等待狀態。
### client
http模塊提供了兩個函數 `http.request`和 `http.get`,功能是作為客戶端向http服務器發起請求。
* http.request(options,callback)
options是一個類似關聯數組的對象,表示請求的參數,callback作為回調函數,http.request返回一個http.ClientRequest的實例。
options常用的參數有host、port(默認為80)、method(默認為GET)、path(請求的相對于根的路徑,默認是“/”,其中querystring應該包含在其中,例如/search?query=byvoid)、headers(請求頭內容) var http=require("http");
http.get(options,callback)
這個方法是http.request方法的簡化版,唯一的區別是http.get自動將請求方法設為了GET請求,同時不需要手動調用req.end(),但是需要記住的是,如果我們使用http.request方法時沒有調用end方法,服務器將不會收到信息。
### Agent:
http.Agent 主要是為 http.request, http.get 提供代理服務的,用于管理 http 連接的創建,銷毀及復用工作。http.request, http.get 默認使用 http.globalAgent 作為代理,每次請求都是“建立連接-數據傳輸-銷毀連接”的過程,如果我們想讓多個請求復用同一個 connection,則需要重新定義 agent 去覆蓋默認的 http.globalAgent,下面我們看一下新建一個agent的需要哪些主要參數:
* keepAlive:{Boolean} 是否開啟 keepAlive,多個請求公用一個 socket connection,默認是 false。
* maxSockets:{Number} 每臺主機允許的socket的最大值,默認值為Infinity。
* maxFreeSockets:{Number} 處于連接池空閑狀態的最大連接數, 僅當開啟 keepAlive 才有效。
~~~text
let http = require('http');
const keepAliveAgent = new http.Agent({
keepAlive: true,
maxScokets: 1000,
maxFreeSockets: 50
})
http.get({
hostname: 'localhost',
port: 80,
path: '/',
agent: keepAliveAgent
}, (res) => {
// Do stuff with response
});
~~~
只有向相同的 host 和 port 發送請求才能公用同一個 keepAlive 的 socket 連接,如果開啟 keepAlive ,同一時間內多個請求會被放在隊列里等待;如果當前隊列為空,該 socket 處于空閑狀態,但是不會被銷毀,等待下一次請求的到來。
使用 keepAlive 代理,有效的減少了建立/銷毀連接的開銷,開發者可以對連接池進行動態管理。
大體差不多就是這個意思,詳細可以看[Node.js 官方文檔](https://link.zhihu.com/?target=https%3A//nodejs.org/docs/latest-v8.x/api/http.html%23http_new_agent_options)
## net
net模塊是同樣是nodejs的核心模塊。在http模塊概覽里提到,http.Server繼承了net.Server,此外,http客戶端與http服務端的通信均依賴于socket(net.Socket)。也就是說,做node服務端編程,net基本是繞不開的一個模塊。
從組成來看,net模塊主要包含兩部分,了解socket編程的同學應該比較熟悉了:
* net.Server:TCP server,內部通過socket來實現與客戶端的通信。
* net.Socket:tcp/本地 socket的node版實現,它實現了全雙工的stream接口。
http是單工的。
```js
/*
In the node.js intro tutorial (http://nodejs.org/), they show a basic tcp
server, but for some reason omit a client connecting to it. I added an
example at the bottom.
Save the following server in example.js:
*/
var net = require('net');
var server = net.createServer(function(socket) {
socket.write('Echo server\r\n');
socket.pipe(socket);
});
server.listen(1337, '127.0.0.1');
/*
And connect with a tcp client from the command line using netcat, the *nix
utility for reading and writing across tcp/udp network connections. I've only
used it for debugging myself.
$ netcat 127.0.0.1 1337
You should see:
> Echo server
*/
/* Or use this example tcp client written in node.js. (Originated with
example code from
http://www.hacksparrow.com/tcp-socket-programming-in-node-js.html.) */
var net = require('net');
var client = new net.Socket();
client.connect(1337, '127.0.0.1', function() {
console.log('Connected');
client.write('Hello, server! Love, Client.');
});
client.on('data', function(data) {
console.log('Received: ' + data);
client.destroy(); // kill client after server's response
});
client.on('close', function() {
console.log('Connection closed');
});
```
## events
->EventEmitter
## fs