首頁 web前端 js教程 在NODEJS中詳細介紹http實現

在NODEJS中詳細介紹http實現

Jun 13, 2018 pm 05:31 PM
http nodejs

這篇文章主要介紹了詳解NODEJS的http實現的技術流程以及詳細分析,需要的朋友學習參考下。

一、前言

目前,HTTP協定是網路上應用最廣泛的網路協議,也是前端er接觸最多的一種協議。透過閱讀http模組在nodejs中的實現,能夠更深入的了解HTTP協定。 HTTP協定是基於TCP協定之上的應用層協議,它的實作離不開TCP/IP協定族。而具體到程式碼實現,http模組依賴net模組。

如下圖所示:在nodejs中,http透過net模組傳輸數據,得到數據之後依賴HTTP_PARSER對數據進行解析。

二、原始碼

啟動一個HTTP服務

nodejs中啟動一個HTTP服務很簡單,就是實例化一個Server對象,並且監聽某個連接埠:

const Server = require('./libs/http').Server
const server = new Server( function(req, res) { 
 res.writeHead(200)
 res.end('hello world')
})
server.listen(9999)
登入後複製

SERVER類別

Server類別繼承於net.Server,並監聽'connection'事件。

在Server類別中,主要做了兩件事: 1. 初始化NET模組並建立TCP網路監聽2. 監聽自身的request事件

當客戶端請求到來的時候,Server實例會先監聽到'connection' 事件,建立起TCP連線並在connectionListener中揭露socket物件。接下來,HTTP模組就透過socket物件與客戶端進行資料互動。

當一個請求到來後,Server會觸發自身的 request 事件,呼叫 requestListener 方法,也就是建立Server實例時傳入的回呼函數。

new Server( function(req, res) { 
 res.writeHead(200)
 res.end('hello world')
})
登入後複製

註: socket物件類似於TCP協定的一個實現,可以透過它與客戶端進行資料交互注: 在connectionListener 函數中,也初始化了parser實例,並給它綁定了一個onIncoming 函數HTTP Parser
整個解析流程在connectionListener 中進行,socket 透過'data' 事件取得TCP推入的資料

當socket取得到資料之後,會先對資料進行解析,即:parser.excute (),解析工具是parser。值得說明的是,作者為了實現對 parser 的重用, parser是從一個'FreeList池'中取得的。

...
const parser = parsers.alloc() 
...
connectionListener(socket) { 
  socket.on('data', socketOnData)

  // TCP推入数据,parser进行解析
  function socketOnData(d) {
    ...
    const ret = parser.execute(d)
    ...
  }
}
登入後複製

1、TCP資料到達時, 先執行execute()

2、順藤摸瓜,我們發現parser.excute 就是 Excute(node_http_parser.cc)。而Excute也只是一個外包而已,具體工作是http_parser_excute(http_parser.c)搞定的。

node_http_parser.cc 只是對 http_parser.c 的一層包裝,http_parser.c依靠對外暴露的7個回呼週期函數與 node_http_parser.cc 進行資料交互。

3、http_parser.c只有兩類回呼:HTTP_CB、HTTP_DATA_CB。透過重載的方式,在這兩類函數中註冊了8個週期函數,如下圖:

4、雖然http_parser註冊有8個回呼函數,但node_http_parser.cc 對外只暴露出四個週期函數:

parserOnHeaders

parserOnHeadersComplete

parserOnBody

parserOnMessageComplete

5、當http_parser.c 解析到on_headers_complete

5、當http_parser.c 解析到on_headers_complete 時,執行HTTP_CB( on_headers_complete)回呼函數,如圖:

函數內會執行kOnHeadersComplete 回呼函數,即:parserOnHeadersComplete 函數(common.js)

6、此時請求頭解析基本完成,接下來建立一個IncomingMessage的實例,然後把請求頭資料包裝到該實例上。

執行 onIncoming 回呼函數,並把得到的IncomingMessage實例當作參數傳遞進去。

function parserOnHeadersComplete (versionMajor, versionMinor, headers, method, url, statusCode, statusMessage, upgrade, shouldKeepAlive) { 
  ...
  parser.incoming = new IncomingMessage(parser.socket)
  parser.incoming.httpVersionMajor = versionMajor
  parser.incoming.httpVersionMinor = versionMinor
  parser.incoming.httpVersion = versionMajor + '.' + versionMinor
  parser.incoming.url = url
  ...
  skipBody = parser.onIncoming(parser.incoming, shouldKeepAlive)

}
登入後複製

7、 在 parserOnIncoming 中,建立一個ServerResponse實例。

具備了req、res兩個實例,接下來觸發Server監聽的 request 事件。

在 Server 實例化時的,requestListener是作為函數參數對 request 事件進行監聽的。

8、回到Server建立時:

const server = new Server( function(req, res) { 
  var data = ''
  req.on('data', function(chunk){
    console.log('chunk: ' + chunk)
    data += chunk;
  })
  res.writeHead(200)
  res.end('hello world')
})
登入後複製

綜上所述,http_parser 解析完 header 之後,就會觸發 request 事件。

那body資料放到哪裡呢,其實body資料會一直放到流裡面,直到使用者使用data事件接收資料。也就是說,觸發request的時候,body並不會被解析。 三、流程梳理

完整的http要求是這樣的: - 客戶端發起HTTP請求,首先觸發Server端的connection事件,建立TCP連結。

Server接收connection事件後,建立TCP連接,並揭露出套接字,透過套接字監聽'data'事件;初始化http-parser,為後續解析資料備用。

HTTP請求資料到達Server端,parser執行execute方法進行解析,請求頭解析成功後,透過回呼觸發request事件。

至此,我們在Server回呼函數中,就接收到了此次http請求的request四、結語

######

由於nodejs不少底層函式庫都是C /C寫的,在閱讀、調試的過程中非常不便。我自己在讀取原始碼的時候,也只是著重看的JS部分原始碼。例如,TCP的三次握手、四次揮手,就沒深究它的實現細節。以上分析沒有涉及http-body的解析,對於有body的網路請求,實際情況要更加複雜一些,還有一些細節沒有完全搞清。等下次總結、分享,我會盡量把漏掉細節都補上。

上面是我整理給大家的,希望今後對大家有幫助。

相關文章:

使用JS取得節點元素的方法

#使用NodeJS如何實作WebSocket功能

有關Express中log4js實際用法

以上是在NODEJS中詳細介紹http實現的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

nodejs是後端框架嗎 nodejs是後端框架嗎 Apr 21, 2024 am 05:09 AM

Node.js 可作為後端框架使用,因為它提供高效能、可擴展性、跨平台支援、豐富的生態系統和易於開發等功能。

nodejs怎麼連接mysql資料庫 nodejs怎麼連接mysql資料庫 Apr 21, 2024 am 06:13 AM

要連接 MySQL 資料庫,需要遵循以下步驟:安裝 mysql2 驅動程式。使用 mysql2.createConnection() 建立連接對象,其中包含主機位址、連接埠、使用者名稱、密碼和資料庫名稱。使用 connection.query() 執行查詢。最後使用 connection.end() 結束連線。

nodejs安裝目錄裡的npm與npm.cmd檔有什麼差別 nodejs安裝目錄裡的npm與npm.cmd檔有什麼差別 Apr 21, 2024 am 05:18 AM

Node.js 安裝目錄中有兩個與 npm 相關的文件:npm 和 npm.cmd,區別如下:擴展名不同:npm 是可執行文件,npm.cmd 是命令視窗快捷方式。 Windows 使用者:npm.cmd 可以在命令提示字元中使用,npm 只能從命令列執行。相容性:npm.cmd 特定於 Windows 系統,npm 跨平台可用。使用建議:Windows 使用者使用 npm.cmd,其他作業系統使用 npm。

nodejs中的全域變數有哪些 nodejs中的全域變數有哪些 Apr 21, 2024 am 04:54 AM

Node.js 中存在以下全域變數:全域物件:global核心模組:process、console、require執行階段環境變數:__dirname、__filename、__line、__column常數:undefined、null、NaN、Infinity、-Infinity

nodejs和java的差別大嗎 nodejs和java的差別大嗎 Apr 21, 2024 am 06:12 AM

Node.js 和 Java 的主要差異在於設計和特性:事件驅動與執行緒驅動:Node.js 基於事件驅動,Java 基於執行緒驅動。單執行緒與多執行緒:Node.js 使用單執行緒事件循環,Java 使用多執行緒架構。執行時間環境:Node.js 在 V8 JavaScript 引擎上運行,而 Java 在 JVM 上運行。語法:Node.js 使用 JavaScript 語法,而 Java 使用 Java 語法。用途:Node.js 適用於 I/O 密集型任務,而 Java 適用於大型企業應用程式。

nodejs是後端開發語言嗎 nodejs是後端開發語言嗎 Apr 21, 2024 am 05:09 AM

是的,Node.js 是一種後端開發語言。它用於後端開發,包括處理伺服器端業務邏輯、管理資料庫連接和提供 API。

nodejs專案怎麼部署到伺服器 nodejs專案怎麼部署到伺服器 Apr 21, 2024 am 04:40 AM

Node.js 專案的伺服器部署步驟:準備部署環境:取得伺服器存取權限、安裝 Node.js、設定 Git 儲存庫。建置應用程式:使用 npm run build 產生可部署程式碼和相依性。上傳程式碼到伺服器:透過 Git 或檔案傳輸協定。安裝依賴項:SSH 登入伺服器並使用 npm install 安裝應用程式相依性。啟動應用程式:使用 node index.js 等命令啟動應用程序,或使用 pm2 等進程管理器。設定反向代理(可選):使用 Nginx 或 Apache 等反向代理路由流量到應用程式

nodejs和java選哪個 nodejs和java選哪個 Apr 21, 2024 am 04:40 AM

Node.js 和 Java 在 Web 開發中各有優劣,因此選擇取決於專案需求。 Node.js 擅長即時應用程式、快速開發和微服務架構,而 Java 則在企業級支援、效能和安全性方面佔優。

See all articles