ホームページ ウェブフロントエンド jsチュートリアル NODEJS での http 実装の詳細な紹介

NODEJS での http 実装の詳細な紹介

Jun 13, 2018 pm 05:31 PM
http nodejs

この記事では主に、NODEJS の http 実装の技術的なプロセスと詳細な分析を紹介します。必要な方は参考にしてください。

1. はじめに

現在、HTTP プロトコルはインターネット上で最も広く使用されているネットワーク プロトコルであり、フロントエンド ER が最も頻繁に使用するプロトコルでもあります。 nodejs の http モジュールの実装を読むことで、HTTP プロトコルをより深く理解できます。 HTTP プロトコルは、TCP プロトコルに基づくアプリケーション層プロトコルであり、その実装は TCP/IP プロトコル ファミリと切り離すことができません。コードの実装に関しては、http モジュールは net モジュールに依存します。

以下の図に示すように、nodejs では、http は net モジュールを通じてデータを送信し、データを取得した後、HTTP_PARSER に依存してデータを解析します。

2. ソースコード

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 クラスでは、2 つの主な処理が行われます: 1. NET モジュールを初期化し、TCP ネットワーク監視を確立します。 2. 独自の要求イベントを監視します

クライアント要求が来ると、Server インスタンスは最初に「接続」をリッスンします。イベントを実行し、TCP 接続を確立し、connectionListener でソケット オブジェクトを公開します。次に、HTTP モジュールはソケット オブジェクトを通じてクライアントと対話します。

リクエストが到着すると、サーバーは独自のリクエスト イベントをトリガーし、サーバー インスタンスの作成時に渡されるコールバック関数である requestListener メソッドを呼び出します。

new Server( function(req, res) { 
 res.writeHead(200)
 res.end('hello world')
})
ログイン後にコピー

注: ソケット オブジェクトは、クライアントとデータを交換できる TCP プロトコルの実装に似ています。 注: connectionListener 関数では、パーサー インスタンスも初期化され、onIncoming 関数 HTTP パーサーがバインドされます。
全体 解析プロセスは connectionListener で実行され、ソケットは「data」イベントを通じて TCP によってプッシュされたデータを取得します。つまり、parser.excute() によってデータが解析されます。解析ツールはパーサーです。パーサーの再利用を実現するために、作成者は「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 つのコールバック定期関数に依存します。

3. http_parser.c には、HTTP_CB と HTTP_DATA_CB の 2 種類のコールバックのみがあります。オーバーロードにより、以下に示すように、これら 2 種類の関数に 8 つの周期関数が登録されます。

4. http_parser には 8 つの登録されたコールバック関数がありますが、node_http_parser.cc は 4 つの周期関数のみを外部に公開します:

parserOnHeaders

parserOnHeadersComplete

parserOnBody

parserOnMessageComplete

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 の 2 つのインスタンスにより、サーバーによって監視されているリクエスト イベントがトリガーされます。

サーバーがインスタンス化されると、リクエストイベントを監視するための関数パラメータとして requestListener が使用されます。

8. サーバーの作成時に戻ります:

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 がヘッダーを解析した後、リクエスト イベントがトリガーされます。

本体データをどこに置くか? 実際、本体データは、ユーザーがデータイベントを使用してデータを受信するまでストリームに配置されます。つまり、リクエストがトリガーされたとき、本文は解析されません。

3. プロセスの概要 完全な http リクエストは次のとおりです: - クライアントは HTTP リクエストを開始し、最初にサーバー側で接続イベントをトリガーし、TCP リンクを確立します。

接続イベントを受信した後、サーバーは TCP 接続を確立し、ソケットを公開し、ソケットを通じて「データ」イベントをリッスンし、その後のデータの解析に備えて http-parser を初期化します。

HTTP リクエスト データがサーバーに到着し、パーサーが実行メソッドを実行して解析します。リクエスト ヘッダーが正常に解析された後、コールバックを通じてリクエスト イベントがトリガーされます。

この時点で、サーバーのコールバック関数でこの http リクエストのリクエストを受け取りました

4. 結論

nodejs の基礎となるライブラリの多くは C++/C で書かれているため、読み取りやデバッグのプロセス中に非常に不便です。私自身ソース コードを読むときは、ソース コードの JS 部分だけに注目しました。たとえば、TCP の 3 ウェイ ハンドシェイクと 4 ウェイ ウェーブは、その実装の詳細については詳しく説明されていません。 上記の分析には http-body の分析は含まれていません。ボディを含むネットワーク リクエストの場合、実際の状況はさらに複雑で、一部の詳細は完全には理解されていません。次回要約して共有するときは、不足している詳細をすべて埋めるように最善を尽くします。

上記は私があなたのためにまとめたものです。

関連記事:

JSを使ってノード要素を取得する方法

NodeJSを使ったWebSocket機能の実装方法

Expressにおけるlog4jsの実際の使い方について

以上がNODEJS での http 実装の詳細な紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

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.cmd という 2 つの npm 関連ファイルがあります。違いは次のとおりです。拡張子が異なります。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 には次のグローバル変数が存在します。 グローバル オブジェクト: グローバル コア モジュール: プロセス、コンソール、require ランタイム環境変数: __dirname、__filename、__line、__column 定数: unknown、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

Web 開発において Node.js と Java にはそれぞれ長所と短所があり、どちらを選択するかはプロジェクトの要件によって異なります。 Node.js はリアルタイム アプリケーション、迅速な開発、マイクロサービス アーキテクチャに優れており、Java はエンタープライズ グレードのサポート、パフォーマンス、セキュリティに優れています。

See all articles