이 글은 주로 Node Inspector 프록시의 구현을 소개합니다. 편집자는 이것이 꽤 좋다고 생각합니다. 이제 여러분과 공유하고 참고할 것입니다. 편집자를 따라 살펴보겠습니다. 모두에게 도움이 되기를 바랍니다.
Background
노드 개발을 할 때 노드 검사기를 통한 중단점 디버깅은 매우 일반적인 디버깅 방법입니다. 그러나 디버깅 효율성을 저하시키는 몇 가지 문제가 있습니다.
질문 1: 중단점 디버깅을 위해 vscode를 사용할 때 애플리케이션이 클러스터를 통해 시작된 검사기인 경우 작업자가 중단되고 다시 시작될 때마다 검사기의 포트가 자동으로 증가합니다. InspectionPort 고정 디버깅 포트는 node8.x 버전에서 지정할 수 있지만 node6.x에서는 지원되지 않습니다. 이로 인해 작업자가 다시 시작될 때마다 vscode에서 디버깅 포트가 다시 지정됩니다.
질문 2: 디버깅을 위해 devtools 링크를 매번 디버깅을 위해 chrome에 복사해야 합니다. 위에서 언급한 포트 변경 문제로 인해 devtools 링크가 검사기를 다시 시작할 때마다 변경됩니다. 또한 websocket ID가 변경되었기 때문에 devtools의 링크도 변경됩니다.
위의 두 가지 문제를 단순화하려면:
vscode에서 디버그하고, 검사기 포트가 변경되거나 웹소켓 ID가 변경된 후 다시 연결할 수 있습니다.
devtools에서 디버그하고 검사기 포트가 변경되거나 웹소켓 ID가 변경된 후 다시 연결할 수 있습니다.
솔루션
현재 업계에는 Chrome 플러그인 Node Inspector Manager(Nim)라는 솔루션이 있습니다. 그러나 이는 동일한 검사기 포트에서 애플리케이션을 다시 시작한 후에만 링크 변경 문제를 해결할 수 있습니다. , 그러나 클러스터 시작으로 인해 발생하는 문제는 해결할 수 없습니다. Nim에 여러 포트가 미리 지정되어 있지 않고 Nim이 Chrome의 플러그인이 아니면 vscode에서 디버깅을 위해 아무 것도 할 수 없다는 것이 자체 증가 포트의 문제입니다.
따라서 가장 좋은 해결책은 당연히 노드를 검사기 프록시로 사용하는 것입니다. 해결책은 다음과 같습니다.
첫 번째 문제의 경우 vscode에서는 /json 인터페이스를 호출하여 최신 websocket ID를 가져온 다음 The를 사용합니다. 새로운 websocket ID가 노드 검사기 서비스에 연결됩니다. 따라서 해결책은 데이터 전달을 위한 TCP 프록시 기능을 구현하는 것입니다.
두 번째 질문의 경우 devtools가 새 websocket ID를 자동으로 가져오지 않기 때문에 동적 교체를 수행해야 합니다. 따라서 해결책은 프록시 서비스를 사용하여 /json에서 websocket ID를 가져온 다음 도중에 websocket ID를 변경하는 것입니다. websocket 핸드셰이크 ID는 요청 헤더에서 동적으로 대체됩니다.
흐름도를 그렸습니다:
구현 단계
1. Tcp 프록시
먼저 tcp 프록시 기능을 구현합니다. 실제로는 매우 간단합니다. 노드의 net 모듈에 연결한 다음 연결이 있을 때 대상 포트에 대한 연결을 생성하면 데이터가 전달될 수 있습니다.
간단한 구현은 다음과 같습니다.
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);
위에서는 파이프 방식을 통해 두 서비스의 데이터를 연결하는 비교적 간단한 프록시 서비스를 구현합니다. 클라이언트에 데이터가 있으면 서버로 전달되고, 서버에 데이터가 있으면 클라이언트에도 전달됩니다.
이 Tcp 프록시 기능을 완료한 후 vscode의 디버깅 요구 사항을 실현할 수 있습니다. vscode의 프로젝트 아래에 있는 launch.json의 포트를 프록시 포트로 지정하고 구성을 구성
{ "type": "node", "request": "attach", "name": "Attach", "protocol": "inspector", "restart": true, "port": 9229 }
에 추가합니다. 그런 다음 애플리케이션이 다시 시작됩니다. , 또는 검사 포트를 교체하면 vscode가 프록시 포트를 통해 애플리케이션에 자동으로 다시 연결할 수 있습니다.
2. WebsocketId 획득
이 단계는 devtools 링크가 변경되지 않은 경우 다시 연결할 수 있는 문제를 해결하기 위해 시작됩니다. 노드 검사기 서버를 시작할 때 검사기 서비스는 웹소켓 ID 가져오기를 위한 /json http 인터페이스도 제공합니다.
이것은 매우 간단합니다. 대상 포트의 /json에 http 요청을 보내면 데이터를 얻을 수 있습니다.
[ { 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 필드는 우리에게 필요한 웹소켓 ID입니다.
3. Inspector 프록시
웹소켓 ID를 얻은 후 tcp 프록시에서 웹소켓 ID를 동적으로 바꿀 수 있습니다. 먼저 고정 링크가 필요하므로 먼저 프록시 서비스 포트를 설정합니다. . 그런 다음 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__ 나머지는 수정되었으며, 마지막 것은 웹소켓 링크로 한눈에 알 수 있습니다. 그중에서 __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 중국어 웹사이트의 기타 관련 기사를 참조하세요!