microsoft/vscode-react-native

Public

mirrored from https://github.com/microsoft/vscode-react-nativeAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
2c19da7f131d11b4265a94fe25139194a565116e

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

src/cdp-proxy/reactNativeCDPProxy.ts

127lines · modecode

1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for details.
3
4import {
5 Connection,
6 Server,
7 WebSocketTransport,
8 IProtocolCommand,
9 IProtocolError,
10 IProtocolSuccess
11} from "vscode-cdp-proxy";
12import { IncomingMessage } from "http";
13import { OutputChannelLogger } from "../extension/log/OutputChannelLogger";
14import { LogLevel } from "../extension/log/LogHelper";
15import { DebuggerEndpointHelper } from "./debuggerEndpointHelper";
16import { ICDPMessageHandler } from "./CDPMessageHandlers/ICDPMessageHandler";
17
18export class ReactNativeCDPProxy {
19
20 private readonly PROXY_LOG_TAGS = {
21 DEBUGGER_COMMAND: "Command Debugger To Target",
22 APPLICATION_COMMAND: "Command Target To Debugger",
23 DEBUGGER_REPLY: "Reply From Debugger To Target",
24 APPLICATION_REPLY: "Reply From Target To Debugger",
25 };
26
27 private server: Server | null;
28 private hostAddress: string;
29 private port: number;
30 private debuggerTarget: Connection;
31 private applicationTarget: Connection;
32 private logger: OutputChannelLogger;
33 private logLevel: LogLevel;
34 private debuggerEndpointHelper: DebuggerEndpointHelper;
35 private CDPMessageHandler: ICDPMessageHandler;
36 private applicationTargetPort: number;
37
38 constructor(hostAddress: string, port: number, logLevel: LogLevel = LogLevel.None) {
39 this.port = port;
40 this.hostAddress = hostAddress;
41 this.logger = OutputChannelLogger.getChannel("React Native Chrome Proxy", true, false, true);
42 this.logLevel = logLevel;
43 this.debuggerEndpointHelper = new DebuggerEndpointHelper();
44 }
45
46 public initializeServer(CDPMessageHandler: ICDPMessageHandler, logLevel: LogLevel): Promise<void> {
47 this.logLevel = logLevel;
48 this.CDPMessageHandler = CDPMessageHandler;
49
50 return Server.create({ port: this.port, host: this.hostAddress })
51 .then((server: Server) => {
52 this.server = server;
53 this.server.onConnection(this.onConnectionHandler.bind(this));
54 });
55 }
56
57 public stopServer(): void {
58 if (this.server) {
59 this.server.dispose();
60 this.server = null;
61 }
62 }
63
64 public setApplicationTargetPort(applicationTargetPort: number): void {
65 this.applicationTargetPort = applicationTargetPort;
66 }
67
68 private async onConnectionHandler([debuggerTarget, request]: [Connection, IncomingMessage]): Promise<void> {
69 this.debuggerTarget = debuggerTarget;
70
71 this.debuggerTarget.pause(); // don't listen for events until the target is ready
72
73 const browserInspectUri = await this.debuggerEndpointHelper.getWSEndpoint(`http://localhost:${this.applicationTargetPort}`);
74
75 this.applicationTarget = new Connection(await WebSocketTransport.create(browserInspectUri));
76
77 this.applicationTarget.onError(this.onApplicationTargetError.bind(this));
78 this.debuggerTarget.onError(this.onDebuggerTargetError.bind(this));
79
80 this.applicationTarget.onCommand(this.handleApplicationTargetCommand.bind(this));
81 this.debuggerTarget.onCommand(this.handleDebuggerTargetCommand.bind(this));
82
83 this.applicationTarget.onReply(this.handleApplicationTargetReply.bind(this));
84 this.debuggerTarget.onReply(this.handleDebuggerTargetReply.bind(this));
85
86 this.debuggerTarget.onEnd(this.onDebuggerTargetClosed.bind(this));
87
88 // dequeue any messages we got in the meantime
89 this.debuggerTarget.unpause();
90 }
91
92 private handleDebuggerTargetCommand(evt: IProtocolCommand) {
93 this.CDPMessageHandler.processCDPMessage(evt);
94 this.logger.logWithCustomTag(this.PROXY_LOG_TAGS.DEBUGGER_COMMAND, JSON.stringify(evt, null , 2), this.logLevel);
95 this.applicationTarget.send(evt);
96 }
97
98 private handleApplicationTargetCommand(evt: IProtocolCommand) {
99 this.CDPMessageHandler.processCDPMessage(evt);
100 this.logger.logWithCustomTag(this.PROXY_LOG_TAGS.APPLICATION_COMMAND, JSON.stringify(evt, null , 2), this.logLevel);
101 this.debuggerTarget.send(evt);
102 }
103
104 private handleDebuggerTargetReply(evt: IProtocolError | IProtocolSuccess) {
105 this.CDPMessageHandler.processCDPMessage(evt);
106 this.logger.logWithCustomTag(this.PROXY_LOG_TAGS.DEBUGGER_REPLY, JSON.stringify(evt, null , 2), this.logLevel);
107 this.applicationTarget.send(evt);
108 }
109
110 private handleApplicationTargetReply(evt: IProtocolError | IProtocolSuccess) {
111 this.CDPMessageHandler.processCDPMessage(evt);
112 this.logger.logWithCustomTag(this.PROXY_LOG_TAGS.APPLICATION_REPLY, JSON.stringify(evt, null , 2), this.logLevel);
113 this.debuggerTarget.send(evt);
114 }
115
116 private onDebuggerTargetError(err: Error) {
117 this.logger.error("Error on debugger transport", err);
118 }
119
120 private onApplicationTargetError(err: Error) {
121 this.logger.error("Error on application transport", err);
122 }
123
124 private async onDebuggerTargetClosed() {
125 this.CDPMessageHandler.processCDPMessage({method: "close"});
126 }
127}