Node Inspector 대리 실현

6477 단어 NodeInspector대리
배경
평소에 node 개발 을 할 때 node inspector 를 통 해 정지점 디 버 깅 을 하 는 것 은 자주 사용 하 는 debug 방식 이다.그러나 몇 가지 문제 가 우리 의 디 버 깅 효율 을 떨 어 뜨 릴 수 있다.
문제 1:vscode 를 사용 하여 정지점 디 버 깅 을 할 때 cluster 를 통 해 시작 하 는 inspector 를 사용 하면 워 커 가 재 부팅 을 끊 을 때마다 inspector 의 포트 가 증가 합 니 다.node8.x 버 전에 서 inspectPort 고정 디 버 깅 포트 를 지정 할 수 있 지만 node6.x 에 서 는 지원 되 지 않 습 니 다.이렇게 하면 워 커 가 다시 시작 할 때마다 vscode 에서 디 버 깅 포트 를 다시 지정 해 야 합 니 다.
문제 2:devtools 디 버 깅 을 사용 할 때 디 버 깅 할 때마다 devtools 를 chrome 에 복사 하여 디 버 깅 해 야 합 니 다.위 에서 말 한 포트 변경 문 제 는 devtools 의 링크 변경 을 초래 할 수 있 습 니 다.그 밖 에 inspector 를 다시 시작 할 때마다 devtools 의 링크 가 바 뀌 기 때 문 입 니 다.websocket id 가 바 뀌 었 기 때 문 입 니 다.
위의 두 가지 문 제 를 간소화 하면 다음 과 같다.
  • vscode 에서 디 버 깅 하고 inspector 포트 변경 또는 websocket id 변경 후 다시 연결 할 수 있 습 니 다.
  • devtools 에서 디 버 깅 하고 inspector 포트 변경 또는 websocket id 변경 후 다시 연결 할 수 있 습 니 다.
  • 해결 방안
    현재 업계 에 서 는 chrome 플러그 인Node Inspector Manager(Nim) 을 해결 하 는 방안 이 있 습 니 다.그러나 이 는 같은 inspector 포트 에서 의 응용 재 부팅 후 링크 변경 문 제 를 해결 할 수 있 을 뿐 cluster 시작 으로 인 한 포트 자체 증가 문 제 를 해결 할 수 없습니다.Nim 에서 여러 포트 를 미리 지정 하지 않 는 한 Nim 은 chrome 의 플러그 인 입 니 다.vscode 에서 의 디 버 깅 에 대해 서 는 아무것도 할 수 없습니다.
    그래서 가장 좋 은 해결 방안 은 당연히 node 를 사용 하여 inspector 대 리 를 하 는 것 입 니 다.해결 방안 은 다음 과 같 습 니 다.
    첫 번 째 문제 에 대해 vscode 에 서 는/json 인 터 페 이 스 를 호출 하여 최신 websocket id 를 가 져 온 다음 새로운 websocket id 를 사용 하여 node inspector 서비스 에 연결 합 니 다.따라서 해결 방법 은 tcp 에이전트 기능 을 실현 하여 데이터 전송 을 하면 된다.
    두 번 째 문제 에 대해 devtools 는 새로운 websocket id 를 자동 으로 가 져 오지 않 기 때문에 동적 으로 교체 해 야 합 니 다.따라서 해결 방안 은 프 록 시 서비스 가/json 에 가서 websocket id 를 가 져 온 다음 에 websocket 악수 할 때 websocket id 를 요청 머리 에 동적 으로 교체 하 는 것 입 니 다.
    흐름 도 를 한 장 그 렸 다.

    실현 절차
    Tcp 에이전트
    우선,tcp 프 록 시 기능 을 먼저 실현 하 는 것 은 간단 합 니 다.node 의 net 모듈 을 통 해 프 록 시 포트 의 Tcp Server 를 만 든 다음 에 연결 이 있 을 때 대상 포트 에 연결 하면 됩 니 다.그리고 데이터 전송 을 할 수 있 습 니 다.
    간단 한 실현 은 다음 과 같다.
    
    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);
    
    
    위 에서 비교적 간단 한 대리 서 비 스 를 실현 하고 pipe 방법 을 통 해 두 서비스의 데 이 터 를 연결 시 켰 다.client 에 데이터 가 있 을 때 server 에 전송 되 고 server 에 데이터 가 있 을 때 client 에 전송 된다.
    이 Tcp 프 록 시 기능 이 완료 되면 vscode 의 디 버 깅 수 요 를 실현 할 수 있 습 니 다.vscode 프로젝트 에서 launch.json 에서 포트 를 프 록 시 포트 로 지정 하고 configurations 에 설정 을 추가 합 니 다.
    
    {
     "type": "node",
     "request": "attach",
     "name": "Attach",
     "protocol": "inspector",
     "restart": true,
     "port": 9229
    }
    그러면 응용 프로그램 이 다시 시작 되 거나 inspect 의 포트 를 바 꾸 면 vscode 는 자동 으로 프 록 시 포트 를 통 해 응용 프로그램 에 다시 연결 할 수 있 습 니 다.
    2.websocketId 가 져 오기
    이 단 계 는 devtools 링크 가 변 하지 않 는 상황 에서 다시 attach 할 수 있 는 문 제 를 해결 하기 위해 서 입 니 다.node inspector server 를 시작 할 때 inspector 서 비 스 는 웹 socket 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 필드 는 우리 가 필요 로 하 는 웹 소켓 id 입 니 다.
    3.Inspector 대리
    웹 소켓 id 를 받 으 면 tcp 에이전트 에서 웹 소켓 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__ 을 제외 하고 모두 고정 되 어 있 으 며,마지막 으로 이것 도 한눈 에 웹 소켓 의 링크 임 을 알 수 있다.이 중 __ws_proxy__은 자 리 를 차지 하 는 데 사 용 됩 니 다.chrome devtools 가 이 프 록 시 링크 에 웹 소켓 악수 요청 을 할 때__ws_proxy__ 를 웹 소켓 id 로 교체 하여 node 의 inspector 서비스 에 전송 합 니 다.
    위의 tcp 에이전트 의pipe 논리 코드 를 약간 수정 하면 됩 니 다.
    
    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);
    ...
    
    
    through 2 를 통 해 transform 흐름 을 만들어 전송 한 데 이 터 를 변경 합 니 다.
    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 를 대응 하 는 웹 소켓 Id 로 교체 한 후 node 의 inspector server 에 전송 하면 웹 소켓 의 악 수 를 완성 할 수 있 습 니 다.다음 웹 소켓 통신 은 데 이 터 를 처리 하지 않 고 직접 전송 하면 됩 니 다.
    다음은 각종 리 셋 애플 리 케 이 션 이나 inspector 포트 를 바 꾸 더 라 도 debug 링크 를 바 꿀 필요 가 없습니다.inspector server 를 다시 시작 할 때 다음 그림 의 팝 업 창 에 있 습 니 다.

    Reconnect DevTools 를 누 르 면 debug 를 복구 할 수 있 습 니 다.
    마지막.
    위의 자세 한 코드 는 아래 git 에서 찾 을 수 있 습 니 다.
  • Tcp 대리:https://github.com/whxaxes/tcp-proxy.js
  • Inspector 대리:https://github.com/whxaxes/inspector-proxy
  • 이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기