diff --git a/src/cdp-proxy/reactNativeCDPProxy.ts b/src/cdp-proxy/reactNativeCDPProxy.ts index dfd947afd..d0664675a 100644 --- a/src/cdp-proxy/reactNativeCDPProxy.ts +++ b/src/cdp-proxy/reactNativeCDPProxy.ts @@ -2,6 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for details. import { IncomingMessage } from "http"; +import { URL } from "url"; import { Connection, Server, @@ -11,6 +12,7 @@ import { IProtocolSuccess, } from "vscode-cdp-proxy"; import { CancellationToken, EventEmitter } from "vscode"; +import * as WebSocket from "ws"; import { OutputChannelLogger } from "../extension/log/OutputChannelLogger"; import { LogLevel } from "../extension/log/LogHelper"; import { DebuggerEndpointHelper } from "./debuggerEndpointHelper"; @@ -123,9 +125,7 @@ export class ReactNativeCDPProxy { } } - this.applicationTarget = new Connection( - await WebSocketTransport.create(this.browserInspectUri), - ); + this.applicationTarget = new Connection(await this.createApplicationTransport()); this.applicationTarget.onError(this.onApplicationTargetError.bind(this)); this.debuggerTarget.onError(this.onDebuggerTargetError.bind(this)); @@ -214,6 +214,35 @@ export class ReactNativeCDPProxy { this.logger.error("Error on application transport", err); } + private createApplicationTransport(): Promise { + const webSocket = new WebSocket(this.browserInspectUri, [], { + perMessageDeflate: false, + maxPayload: 256 * 1024 * 1024, + origin: ReactNativeCDPProxy.getWebSocketOrigin(this.browserInspectUri), + } as WebSocket.IClientOptions & { maxPayload: number; perMessageDeflate: boolean }); + + return new Promise((resolve, reject) => { + webSocket.once("open", () => { + resolve(new WebSocketTransport(webSocket)); + }); + webSocket.once("error", reject); + }); + } + + private static getWebSocketOrigin(webSocketUrl: string): string | undefined { + const url = new URL(webSocketUrl); + + if (url.protocol === "ws:") { + return `http://${url.host}`; + } + + if (url.protocol === "wss:") { + return `https://${url.host}`; + } + + return undefined; + } + private async onApplicationTargetClosed() { this.applicationTarget = null; this.applicationTargetEventEmitter.fire({}); diff --git a/src/extension/reactNativeSessionManager.ts b/src/extension/reactNativeSessionManager.ts index 62438be97..3bb81dbd2 100644 --- a/src/extension/reactNativeSessionManager.ts +++ b/src/extension/reactNativeSessionManager.ts @@ -23,7 +23,7 @@ export class ReactNativeSessionManager ): vscode.ProviderResult { const rnSession = new RNSession(session); - let debugServer; + let debugServer: Net.Server; if (session.configuration.platform != "expoweb") { debugServer = Net.createServer(socket => { const rnDebugSession = @@ -45,11 +45,18 @@ export class ReactNativeSessionManager }); } - debugServer.listen(0, "127.0.0.1"); - this.servers.set(session.id, debugServer); + return new Promise((resolve, reject) => { + debugServer.once("error", reject); + debugServer.listen(0, "127.0.0.1", () => { + debugServer.removeListener("error", reject); + this.servers.set(session.id, debugServer); - // make VS Code connect to debug server - return new vscode.DebugAdapterServer((debugServer.address()).port); + // make VS Code connect to debug server + resolve( + new vscode.DebugAdapterServer((debugServer.address()).port), + ); + }); + }); } public terminate(terminateEvent: TerminateEventArgs): void { diff --git a/test/cdp-proxy/reactNativeCDPProxy.test.ts b/test/cdp-proxy/reactNativeCDPProxy.test.ts index 30ee415ef..521c47b6f 100644 --- a/test/cdp-proxy/reactNativeCDPProxy.test.ts +++ b/test/cdp-proxy/reactNativeCDPProxy.test.ts @@ -290,9 +290,10 @@ suite("reactNativeCDPProxy", function () { generateRandomPortNumber(), ); const debuggerTarget = createConnectionStub(); - const createWebSocketTransportStub = Sinon.stub(WebSocketTransport, "create").returns( - Promise.resolve(createTransportStub()), - ); + const createApplicationTransportStub = Sinon.stub( + localProxy as any, + "createApplicationTransport", + ).returns(Promise.resolve(createTransportStub())); Object.assign(localProxy, { browserInspectUri: "ws://localhost:1234/debugger", @@ -310,7 +311,7 @@ suite("reactNativeCDPProxy", function () { }, ]); } finally { - createWebSocketTransportStub.restore(); + createApplicationTransportStub.restore(); } assert.strictEqual(debuggerTarget.close.called, false);