microsoft/vscode-react-native

Public

mirrored fromhttps://github.com/microsoft/vscode-react-nativeAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
984ca036ea8e629228ba7ebe24a22b2ea2415fe1

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/cdp-proxy/reactNativeCDPProxy.ts

163lines · 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 | null;
32 private logger: OutputChannelLogger;
33 private logLevel: LogLevel;
34 private debuggerEndpointHelper: DebuggerEndpointHelper;
35 private CDPMessageHandler: ICDPMessageHandler;
36 private applicationTargetPort: number;
37 private browserInspectUri: string;
38
39 constructor(hostAddress: string, port: number, logLevel: LogLevel = LogLevel.None) {
40 this.port = port;
41 this.hostAddress = hostAddress;
42 this.logger = OutputChannelLogger.getChannel("React Native Chrome Proxy", true, false, true);
43 this.logLevel = logLevel;
44 this.browserInspectUri = "";
45 this.debuggerEndpointHelper = new DebuggerEndpointHelper();
46 }
47
48 public initializeServer(CDPMessageHandler: ICDPMessageHandler, logLevel: LogLevel): Promise<void> {
49 this.logLevel = logLevel;
50 this.CDPMessageHandler = CDPMessageHandler;
51
52 return Server.create({ port: this.port, host: this.hostAddress })
53 .then((server: Server) => {
54 this.server = server;
55 this.server.onConnection(this.onConnectionHandler.bind(this));
56 });
57 }
58
59 public async stopServer(): Promise<void> {
60 if (this.server) {
61 this.server.dispose();
62 this.server = null;
63 }
64
65 if (this.applicationTarget) {
66 await this.applicationTarget.close();
67 this.applicationTarget = null;
68 }
69
70 this.browserInspectUri = "";
71 }
72
73 public setBrowserInspectUri(browserInspectUri: string) {
74 this.browserInspectUri = browserInspectUri;
75 }
76
77 public setApplicationTargetPort(applicationTargetPort: number): void {
78 this.applicationTargetPort = applicationTargetPort;
79 }
80
81 private async onConnectionHandler([debuggerTarget, request]: [Connection, IncomingMessage]): Promise<void> {
82 this.debuggerTarget = debuggerTarget;
83
84 this.debuggerTarget.pause(); // don't listen for events until the target is ready
85
86 if (!this.browserInspectUri) {
87 this.browserInspectUri = await this.debuggerEndpointHelper.retryGetWSEndpoint(`http://localhost:${this.applicationTargetPort}`, 90);
88 }
89
90 this.applicationTarget = new Connection(await WebSocketTransport.create(this.browserInspectUri));
91
92 this.applicationTarget.onError(this.onApplicationTargetError.bind(this));
93 this.debuggerTarget.onError(this.onDebuggerTargetError.bind(this));
94
95 this.applicationTarget.onCommand(this.handleApplicationTargetCommand.bind(this));
96 this.debuggerTarget.onCommand(this.handleDebuggerTargetCommand.bind(this));
97
98 this.applicationTarget.onReply(this.handleApplicationTargetReply.bind(this));
99 this.debuggerTarget.onReply(this.handleDebuggerTargetReply.bind(this));
100
101 this.debuggerTarget.onEnd(this.onDebuggerTargetClosed.bind(this));
102
103 // dequeue any messages we got in the meantime
104 this.debuggerTarget.unpause();
105 }
106
107 private handleDebuggerTargetCommand(event: IProtocolCommand) {
108 this.logger.logWithCustomTag(this.PROXY_LOG_TAGS.DEBUGGER_COMMAND, JSON.stringify(event, null , 2), this.logLevel);
109 const processedMessage = this.CDPMessageHandler.processDebuggerCDPMessage(event);
110
111 if (processedMessage.sendBack) {
112 this.debuggerTarget.send(processedMessage.event);
113 } else {
114 this.applicationTarget?.send(processedMessage.event);
115 }
116 }
117
118 private handleApplicationTargetCommand(event: IProtocolCommand) {
119 this.logger.logWithCustomTag(this.PROXY_LOG_TAGS.APPLICATION_COMMAND, JSON.stringify(event, null , 2), this.logLevel);
120 const processedMessage = this.CDPMessageHandler.processApplicationCDPMessage(event);
121
122 if (processedMessage.sendBack) {
123 this.applicationTarget?.send(processedMessage.event);
124 } else {
125 this.debuggerTarget.send(processedMessage.event);
126 }
127 }
128
129 private handleDebuggerTargetReply(event: IProtocolError | IProtocolSuccess) {
130 this.logger.logWithCustomTag(this.PROXY_LOG_TAGS.DEBUGGER_REPLY, JSON.stringify(event, null , 2), this.logLevel);
131 const processedMessage = this.CDPMessageHandler.processDebuggerCDPMessage(event);
132
133 if (processedMessage.sendBack) {
134 this.debuggerTarget.send(processedMessage.event);
135 } else {
136 this.applicationTarget?.send(processedMessage.event);
137 }
138 }
139
140 private handleApplicationTargetReply(event: IProtocolError | IProtocolSuccess) {
141 this.logger.logWithCustomTag(this.PROXY_LOG_TAGS.APPLICATION_REPLY, JSON.stringify(event, null , 2), this.logLevel);
142 const processedMessage = this.CDPMessageHandler.processApplicationCDPMessage(event);
143
144 if (processedMessage.sendBack) {
145 this.applicationTarget?.send(processedMessage.event);
146 } else {
147 this.debuggerTarget.send(processedMessage.event);
148 }
149 }
150
151 private onDebuggerTargetError(err: Error) {
152 this.logger.error("Error on debugger transport", err);
153 }
154
155 private onApplicationTargetError(err: Error) {
156 this.logger.error("Error on application transport", err);
157 }
158
159 private async onDebuggerTargetClosed() {
160 this.browserInspectUri = "";
161 this.CDPMessageHandler.processDebuggerCDPMessage({method: "close"});
162 }
163}
164