From fde971a596fe13d7680804a7162c4365f1f61cd6 Mon Sep 17 00:00:00 2001 From: Kristina Koeva Date: Tue, 22 Nov 2016 14:01:47 +0200 Subject: [PATCH] Chrome dev tools Open a web socket proxy when debugging is started with chrome option --- lib/declarations.ts | 4 +- .../ios/socket-proxy-factory.ts | 122 ++++++++---------- lib/options.ts | 3 +- lib/services/ios-debug-service.ts | 18 ++- 4 files changed, 71 insertions(+), 76 deletions(-) diff --git a/lib/declarations.ts b/lib/declarations.ts index 1d80c93fba..d37f69ab5b 100644 --- a/lib/declarations.ts +++ b/lib/declarations.ts @@ -103,6 +103,7 @@ interface IOptions extends ICommonOptions { rebuild: boolean; syncAllFiles: boolean; liveEdit: boolean; + chrome: boolean; } interface IInitService { @@ -233,7 +234,8 @@ interface IAndroidToolsInfoData { } interface ISocketProxyFactory { - createSocketProxy(factory: () => any): IFuture; + createTCPSocketProxy(factory: () => any): any; + createWebSocketProxy(factory: () => any): any; } interface IiOSNotification { diff --git a/lib/device-sockets/ios/socket-proxy-factory.ts b/lib/device-sockets/ios/socket-proxy-factory.ts index 9e98fa51ee..b224bbe699 100644 --- a/lib/device-sockets/ios/socket-proxy-factory.ts +++ b/lib/device-sockets/ios/socket-proxy-factory.ts @@ -1,6 +1,5 @@ import { PacketStream } from "./packet-stream"; import * as net from "net"; -import * as semver from "semver"; import * as ws from "ws"; import temp = require("temp"); import * as helpers from "../../common/helpers"; @@ -12,25 +11,65 @@ export class SocketProxyFactory implements ISocketProxyFactory { private $projectDataService: IProjectDataService, private $options: IOptions) { } - public createSocketProxy(factory: () => net.Socket): IFuture { - return (() => { - let socketFactory = (callback: (_socket: net.Socket) => void) => helpers.connectEventually(factory, callback); + public createTCPSocketProxy(factory: () => net.Socket): any { + let socketFactory = (callback: (_socket: net.Socket) => void) => helpers.connectEventually(factory, callback); - this.$projectDataService.initialize(this.$projectData.projectDir); - let frameworkVersion = this.$projectDataService.getValue("tns-ios").wait().version; - let result: any; + this.$logger.info("\nSetting up proxy...\nPress Ctrl + C to terminate, or disconnect.\n"); - if(semver.gte(frameworkVersion, "1.4.0")) { - result = this.createTcpSocketProxy(socketFactory); - } else { - result = this.createWebSocketProxy(socketFactory); - } + let server = net.createServer({ + allowHalfOpen: true + }); + + server.on("connection", (frontendSocket: net.Socket) => { + this.$logger.info("Frontend client connected."); + + frontendSocket.on("end", () => { + this.$logger.info('Frontend socket closed!'); + if (!(this.$config.debugLivesync && this.$options.watch)) { + process.exit(0); + } + }); - return result; - }).future()(); + socketFactory((backendSocket: net.Socket) => { + this.$logger.info("Backend socket created."); + + backendSocket.on("end", () => { + this.$logger.info("Backend socket closed!"); + if (!(this.$config.debugLivesync && this.$options.watch)) { + process.exit(0); + } + }); + + frontendSocket.on("close", () => { + console.log("frontend socket closed"); + if (!(backendSocket).destroyed) { + backendSocket.destroy(); + } + }); + backendSocket.on("close", () => { + console.log("backend socket closed"); + if (!(frontendSocket).destroyed) { + frontendSocket.destroy(); + } + }); + + backendSocket.pipe(frontendSocket); + frontendSocket.pipe(backendSocket); + frontendSocket.resume(); + }); + }); + + let socketFileLocation = temp.path({ suffix: ".sock" }); + server.listen(socketFileLocation); + if(!this.$options.client) { + this.$logger.info("socket-file-location: " + socketFileLocation); + } + + return server; } - private createWebSocketProxy(socketFactory: (handler: (socket: net.Socket) => void) => void): ws.Server { + public createWebSocketProxy(factory: () => net.Socket): ws.Server { + let socketFactory = (callback: (_socket: net.Socket) => void) => helpers.connectEventually(factory, callback); // NOTE: We will try to provide command line options to select ports, at least on the localhost. let localPort = 8080; @@ -86,58 +125,5 @@ export class SocketProxyFactory implements ISocketProxyFactory { this.$logger.info("Opened localhost " + localPort); return server; } - - private createTcpSocketProxy(socketFactory: (handler: (socket: net.Socket) => void) => void): net.Server { - this.$logger.info("\nSetting up proxy...\nPress Ctrl + C to terminate, or disconnect.\n"); - - let server = net.createServer({ - allowHalfOpen: true - }); - - server.on("connection", (frontendSocket: net.Socket) => { - this.$logger.info("Frontend client connected."); - - frontendSocket.on("end", () => { - this.$logger.info('Frontend socket closed!'); - if (!(this.$config.debugLivesync && this.$options.watch)) { - process.exit(0); - } - }); - - socketFactory((backendSocket: net.Socket) => { - this.$logger.info("Backend socket created."); - - backendSocket.on("end", () => { - this.$logger.info("Backend socket closed!"); - if (!(this.$config.debugLivesync && this.$options.watch)) { - process.exit(0); - } - }); - - frontendSocket.on("close", () => { - if (!(backendSocket).destroyed) { - backendSocket.destroy(); - } - }); - backendSocket.on("close", () => { - if (!(frontendSocket).destroyed) { - frontendSocket.destroy(); - } - }); - - backendSocket.pipe(frontendSocket); - frontendSocket.pipe(backendSocket); - frontendSocket.resume(); - }); - }); - - let socketFileLocation = temp.path({ suffix: ".sock" }); - server.listen(socketFileLocation); - if(!this.$options.client) { - this.$logger.info("socket-file-location: " + socketFileLocation); - } - - return server; - } } $injector.register("socketProxyFactory", SocketProxyFactory); diff --git a/lib/options.ts b/lib/options.ts index 3c7286251b..809af2e8fc 100644 --- a/lib/options.ts +++ b/lib/options.ts @@ -41,7 +41,8 @@ export class Options extends commonOptionsLibPath.OptionsBase { teamId: { type: OptionType.String }, rebuild: { type: OptionType.Boolean, default: true }, syncAllFiles: { type: OptionType.Boolean }, - liveEdit: { type: OptionType.Boolean } + liveEdit: { type: OptionType.Boolean }, + chrome: { type: OptionType.Boolean } }, path.join($hostInfo.isWindows ? process.env.AppData : path.join(osenv.home(), ".local/share"), ".nativescript-cli"), $errors, $staticConfig); diff --git a/lib/services/ios-debug-service.ts b/lib/services/ios-debug-service.ts index addde79051..375bfc4aff 100644 --- a/lib/services/ios-debug-service.ts +++ b/lib/services/ios-debug-service.ts @@ -14,7 +14,7 @@ class IOSDebugService implements IDebugService { private _lldbProcess: ChildProcess; private _sockets: net.Socket[] = []; private _childProcess: ChildProcess; - private _socketProxy: net.Server; + private _socketProxy: any; constructor( private $config: IConfiguration, @@ -30,7 +30,6 @@ class IOSDebugService implements IDebugService { private $injector: IInjector, private $npmInstallationManager: INpmInstallationManager, private $options: IOptions, - private $projectDataService: IProjectDataService, private $utils: IUtils, private $iOSNotification: IiOSNotification, private $iOSSocketRequestExecutor: IiOSSocketRequestExecutor, @@ -190,17 +189,24 @@ class IOSDebugService implements IDebugService { private wireDebuggerClient(device?: Mobile.IiOSDevice): IFuture { return (() => { - this._socketProxy = this.$socketProxyFactory.createSocketProxy(() => { + let factory = () => { let socket = device ? device.connectToPort(inspectorBackendPort) : net.connect(inspectorBackendPort); this._sockets.push(socket); return socket; - }).wait(); + }; + + if (this.$options.chrome) { + this._socketProxy = this.$socketProxyFactory.createWebSocketProxy(factory); - this.openDebuggerClient(this._socketProxy.address()).wait(); + this.$logger.info(`To start debugging, open the following URL in Chrome:\nchrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=localhost:${this._socketProxy.options.port}\n`); + } else { + this._socketProxy = this.$socketProxyFactory.createTCPSocketProxy(factory); + this.openAppInspector(this._socketProxy.address()).wait(); + } }).future()(); } - private openDebuggerClient(fileDescriptor: string): IFuture { + private openAppInspector(fileDescriptor: string): IFuture { if (this.$options.client) { return (() => { let inspectorPath = this.$npmInstallationManager.install(inspectorNpmPackageName).wait();