Node Inspector エージェントの実装例のチュートリアル

小云云
リリース: 2018-01-09 10:29:58
オリジナル
1513 人が閲覧しました

この記事では主に Node Inspector プロキシの実装を紹介します。編集者がそれを参考にさせていただきます。編集者をフォローして見てみましょう。皆さんのお役に立てれば幸いです。

背景

ノード開発を行う場合、ノード インスペクターを使用したブレークポイント デバッグは非常に一般的なデバッグ方法です。ただし、デバッグ効率を低下させる問題がいくつかあります。

質問 1: ブレークポイントのデバッグに vscode を使用する場合、アプリケーションがクラスターを通じて開始されたインスペクターである場合、ワーカーがハングして再起動するたびに、インスペクターのポートが自動的に増加します。バージョン8.xではinspectPort固定デバッグポートを指定できますが、node6.xではサポートされていません。これにより、ワーカーが再起動されるたびに vscode でデバッグ ポートが再指定されます。

質問 2: デバッグに devtools を使用する場合、デバッグのために毎回 devtools リンクを Chrome にコピーする必要があります。また、上記のポート変更の問題により、インスペクターを再起動するたびに devtools リンクが変更されます。 WebSocket ID が変更されたため、devtools のリンクも変更されます。

上記の 2 つの問題を単純化するには:

  • vscode でデバッグすると、インスペクターのポートが変更されるか WebSocket ID が変更された後に再接続できます。

  • devtools でデバッグし、インスペクターのポートが変更された後、または WebSocket ID が変更された後に再接続できるようにします。

解決策

現在、業界にはChromeプラグインNode Inspector Manager (Nim)という解決策がありますが、これは同じインスペクタポートのアプリケーションが再起動された後にのみリンク変更の問題を解決できます。 , しかし、クラスター起動による問題は解決できません。ポートの自己増加の問題は、事前に Nim で複数のポートを指定しておかないと、Nim は chrome 上のプラグインなので、vscode でのデバッグには何もできません。

したがって、最良の解決策は、当然ながら、ノードをインスペクター プロキシとして使用することです。 解決策は次のとおりです。

最初の問題については、vscode で、/json インターフェイスを呼び出して最新の WebSocket ID を取得し、新しい WebSocket ID がノード インスペクター サービスに接続されます。したがって、解決策は、データ転送用の tcp プロキシ機能を実装することです。

2 番目の質問では、devtools は新しい WebSocket ID を自動的に取得しないため、動的置換を行う必要があります。そのため、解決策は、プロキシ サービスを使用して /json から WebSocket ID を取得し、その際に WebSocket ID を変更することです。 WebSocket ハンドシェイク。ID はリクエスト ヘッダー内で動的に置き換えられます。

フローチャートを描きます:

実装手順

1. Tcp プロキシ

まず、tcp プロキシの機能を実装します。実際、これは非常に簡単です。ノードのネット モジュールにアクセスし、接続があるときにターゲット ポートへの接続を作成するだけで、データを転送できます。

簡単な実装は次のとおりです:

const net = require('net');
const proxyPort = 9229;
const forwardPort = 5858;

net.createServer(client => {
 const server = net.connect({
  host: '127.0.0.1',
  port: forwardPort,
 }, () => {
  client.pipe(server).pipe(client);
 });
 // 如果真要应用到业务中,还得监听一下错误/关闭事件,在连接关闭时即时销毁创建的 socket。
}).listen(proxyPort);
ログイン後にコピー

上記は、パイプ メソッドを通じて 2 つのサービスのデータを接続する、比較的単純なプロキシ サービスを実装しています。クライアントにデータがある場合はサーバーに転送され、サーバーにデータがある場合はクライアントにも転送されます。

この Tcp プロキシ機能が完了したら、vscode のプロジェクトの下にある launch.json のポートをプロキシ ポートとして指定し、configuration に設定を追加します

{
 "type": "node",
 "request": "attach",
 "name": "Attach",
 "protocol": "inspector",
 "restart": true,
 "port": 9229
}
ログイン後にコピー

そして、アプリケーションが再起動されると、 、または検査のポートを置き換えると、vscode はプロキシ ポートを介してアプリケーションに自動的に再接続できます。

2. websocketId を取得します

このステップは、ノード インスペクター サーバーの起動時に、devtools リンクを再接続できるという問題の解決を開始します。インスペクター サービスは、WebSocket ID を取得するための /json http インターフェイスも提供します。

これは非常に簡単です。http リクエストをターゲット ポートの /json に送信するだけで、データを取得できます:

[ { description: 'node.js instance',
  devtoolsFrontendUrl: '...',
  faviconUrl: 'https://nodejs.org/static/favicon.ico',
  id: 'e7ef6313-1ce0-4b07-b690-d3cf5274d8b0',
  title: '/Users/wanghx/Workspace/larva-team/vscode-log/index.js',
  type: 'node',
  url: 'file:///Users/wanghx/Workspace/larva-team/vscode-log/index.js',
  webSocketDebuggerUrl: 'ws://127.0.0.1:5858/e7ef6313-1ce0-4b07-b690-d3cf5274d8b0' } ]
ログイン後にコピー

上記のデータの id フィールドは、必要な WebSocket ID です。

3. プロキシの検査

WebSocket ID を取得したら、TCP プロキシの WebSocket ID を動的に置き換えることができます。たとえば、プロキシ サービスのポートを 9229 に設定します。 Chrome devtools のプロキシ リンクは次のとおりです:

chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9229/__ws_proxy__

最後の ws=127.0.0.1 を除く:9229/__ws_proxy__ 他のものは修正されており、最後のものは WebSocket リンクであることが一目でわかります。このうち、__ws_proxy__ はプレースホルダーとして使用されます。chrome devtools がこのプロキシ リンクへの WebSocket ハンドシェイク リクエストを開始すると、__ws_proxy__ が WebSocket ID に置き換えられ、ノードのインスペクター サービスに転送されます。

上記の TCP プロキシのパイプ ロジック コードにいくつかの小さな変更を加えるだけです。

const through = require('through2');
...

client
   .pipe(through.obj((chunk, enc, done) => {
    if (chunk[0] === 0x47 && chunk[1] === 0x45 && chunk[2] === 0x54) {
     const content = chunk.toString();
     if (content.includes('__ws_proxy__')) {
      return done(null, Buffer.from(content.replace('__ws_proxy__', websocketId)));
     }
    }
    done(null, chunk);
   }))
   .pipe(server)
   .pipe(client);
...
ログイン後にコピー

through2 を介して変換ストリームを作成し、送信されたデータにいくつかの変更を加えます。

简单判断一下 chunk 的头三个字节是否为GET,如果是 GET 说明这可能是个 http 请求,也就可能是 websocket 的协议升级请求。把请求头打印出来就是这个样子的:

GET /__ws_proxy__ HTTP/1.1
Host: 127.0.0.1:9229
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: chrome-devtools://devtools
Sec-WebSocket-Version: 13
...
ログイン後にコピー

然后将其中的路径/__ws_proxy替换成对应的 websocketId,然后转发到 node 的 inspector server 上,即可完成 websocket 的握手,接下来的 websocket 通信就不需要对数据做处理,直接转发即可。

接下来就算各种重启应用,或者更换 inspector 的端口,都不需要更换 debug 链接,只需要再 inspector server 重启的时候,在下图的弹窗中

点击一下 Reconnect DevTools 即可恢复 debug。

相关推荐:

Web Inspector:关于在 Sublime Text 中调试Js的介绍_基础知识

Node.js设计模式使用流进行编码

NodeJs之数据库异常处理详解

以上がNode Inspector エージェントの実装例のチュートリアルの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート