この記事では主に 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 Inspector エージェントの実装例のチュートリアルの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。