七、網絡編程
1. 構建 TCP 服務
TCP 是面向連接的協議,顯著特征 在傳輸之前需要3次握手形成會話。
客戶端 ——請求連接——> 服務器端 ——響應——> 客戶端 ——開始傳輸——> 服務器端。
2. 構建 UDP 服務
3. 構建 HTTP 服務
http模塊
在node中HTTP服務繼承自TCP服務器(net模塊),它能夠與多個客戶端保持連接,由于其采用事件驅動的形式,并不為每一個連接創建額外的線程或進程,保持很低的內存占用,所以能實現高并發。
4. 構建 WebSocket 服務
WebSocket協議主要分為兩個部分:握手 和 數據傳輸。
(握手部分由HTTP完成,握手順利完成后當前連接將不再進行HTTP的交互,而是開始WebSocket的數據幀協議)
5. 網絡服務與安全
Node在網絡安全上提供了3個模塊,分別為 crypto、tls、https。
TLS / SSL
1、密鑰
TLS / SSL 是一對公鑰/私鑰 的結構,非對稱結構。
Node 在底層采用的是 openssl 實現TLS/SSL 。
2、數字證書
TLS 服務
HTTPS 服務
6. 總結
Node基于事件驅動和非阻塞設計,在分布式環境中尤其能發揮出它的特長,基于事件驅動可以實現與大量的客戶端進行連接,非阻塞設計則讓它可以更好地提升網絡的響應吞吐。Node提供了相對底層的網絡調用,以及基于事件的編接口,使得開發者在這些模塊上十分輕松地構建網絡應用。
八、構建web應用(重點)
8.1 基礎功能
// 經典案例 Hello World
var http = require('http')
http.createServer( function (req , res){res.writeHead(200,{'Content-Type':'text/plain'});res.end('Hello World\n');
} ).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/')
// 使用 node .\helloWorld.js 運行服務,輸入地址即可訪問。
要實現更豐富的需求,一切都從如下這個函數展開:
function (req , res){res.writeHead(200,{'Content-Type':'text/plain'});res.end();
}
8.1.1 請求方法
在Web應用中最常見的請求方法是 GET 和 POST,除此之外,還有HEAD、DELETE、PUT、CONNECT等方法。
請求方法存在于報文的第一行的第一個單詞,通常大寫。如下為一個報文頭的示例:
8.1.2 路徑解析
路徑部分存在于報文的第一行的第二部分,參考上圖。
8.1.3 查詢字符串
跟在路徑后面的字符串就是查詢字符串(如 ?name=nb)
Node提供了 querystring
模塊用于處理這部分數據:
var querystring = require('querystring');
var query = querystring.parse( url.parse(req.url).query );
// 更簡介的方法是 給 url.parse()傳遞第二個參數,如下
var query2 = url.parse(req.url, true).query;
// 它會將 name=nb&age=120 解析為一個JSON對象 {name:'nb',age:120}
// 如果鍵多次出現,那么它的值將會是一個數組 name=nb1&name=nb2 => {name:['nb1','nb2']}
8.1.4 Cookie
HTTP是一個無狀態的協議,而現實業務中卻是需要一定的狀態的,否者無法區分用戶之間的身份。如何標識和認證一個用戶,最早的方案就是Cookie。
Cookie的處理分為如下幾步:服務器向客戶端發送Cookie => 瀏覽器將Cookie保存 => 之后每次請求都會將Cookie發向服務器;
HTTP_Parser 會將所有的報文字段解析到 req.headers上,那么 Cookie 就是 req.headers.cookie
根據規范中定義 Cookie 值的格式是 key=value;key2=value2 形式的。
8.1.5 Session
問題1:Cookie可能會體積過大;問題2:Cookie可以在前后端進行修改,Cookie對敏感數據的保護可以說是無效的。Session 應運而生。
Session的數據只保留在服務器端,客戶端無法修改。這樣數據安全性得到一定保障,數據也無需在協議中每次都被傳遞。
雖然在服務器端存儲數據十分方便,如何將每個客戶和服務器中的數據一一對應呢?這里有兩種常見的實現方式:
- 基于 Cookie 來實現用戶和數據的映射;P195
- 通過查詢字符串來實現瀏覽器端和服務器端數據的對應;P195(風險大于1)
1.Session 與內存
- Session 弊端:
- 增加內存消耗,會引起性能問題;
- 我們為了利用 多核CPU啟動多個進程時,用戶請求的連接將可能隨意分配到各個進程中,Node的進程與進程之間是不能直接共享內存的,用戶的Session可能會引起錯亂。
- 為解決性能問題和Session數據無法跨進程共享的問題,常用的方案是將Session集中化,如常用的工具 Redis、Memcached等。P198
- 盡管采用第三方緩存會引起網絡訪問,理論上比本地慢,但還是利大于弊。
2.Session 與安全
主要是指如何讓這個口令更加安全。
- 加密 / 解密
- 將客戶端的某些獨有信息與口令作為原始值然后簽名。這樣攻擊者一旦不在原始的客戶端上進行訪問就會導致簽名失敗。
8.1.6 緩存
如何節省不必要的傳輸,提高性能。
8.1.7 Basic認證
P204 --不太重要
8.2 數據上傳
8.3 路由解析
8.4 中間件
8.5 頁面渲染
8.6 總結
- 本章涉及的內容較為豐富,在Web應用的整個構建過程中,從處理請求到響應請求的整個過程都有原理性闡述,整理本章細節就可以完成一個功能完備的Web開發框架。過去的各種Web技術,隨著框架和庫的成型,開發者往往迷糊地知道應用框架和庫,卻不知道細節的實現,這好比沒有地圖卻在野地里行進。本章的內容希望能為Node開發者帶來地圖似的啟發,在開發Web應用時能夠心有輪廓,明了細微。
- 現在知名和成熟的Web框架有Connect、Express等,本章中的內容在這些框架中都有實現因為行文的原因,本章中的代碼實現得較為粗糙,實際使用請使用這些成熟的框架。
P245