From d1c61918acdd21c96a1695102f0b290b3f73ef7d Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Fri, 3 Feb 2017 18:42:25 +0200 Subject: [PATCH 1/8] Remove ios native dependencies We need to remove our native dependencies - ref and ffi because they are casuing problems with each version of NodeJS which has new version of V8 in it. We are using ref and ffi to communicate with iTunes and execute fs and application management operations on iOS devices. This operations are moved in new dependency - device-lib. The device lib has JavaScript wrapper which we use in the CLI. Everything in the ios device file system and ios device application manager is replaced with the exposed methods from the device lib. --- lib/declarations.ts | 3 +- .../ios/socket-request-executor.ts | 42 +++++++++---------- lib/services/ios-debug-service.ts | 11 +++-- lib/services/ios-notification-service.ts | 36 ++++++++-------- .../livesync/ios-device-livesync-service.ts | 10 ++--- package.json | 4 +- test/ios-project-service.ts | 1 + 7 files changed, 53 insertions(+), 54 deletions(-) diff --git a/lib/declarations.ts b/lib/declarations.ts index 2ce2edd905..66847acd53 100644 --- a/lib/declarations.ts +++ b/lib/declarations.ts @@ -304,7 +304,8 @@ interface IiOSNotification { } interface IiOSNotificationService { - awaitNotification(npc: Mobile.INotificationProxyClient, notification: string, timeout: number): Promise; + awaitNotification(deviceIdentifier: string, notification: string, timeout: number): Promise; + postNotification(deviceIdentifier: string, notification: string): Promise; } interface IiOSSocketRequestExecutor { diff --git a/lib/device-sockets/ios/socket-request-executor.ts b/lib/device-sockets/ios/socket-request-executor.ts index 2b5f2d3f78..0e57efd372 100644 --- a/lib/device-sockets/ios/socket-request-executor.ts +++ b/lib/device-sockets/ios/socket-request-executor.ts @@ -1,22 +1,18 @@ -import * as iOSProxyServices from "../../common/mobile/ios/device/ios-proxy-services"; - export class IOSSocketRequestExecutor implements IiOSSocketRequestExecutor { constructor(private $errors: IErrors, - private $injector: IInjector, private $iOSNotification: IiOSNotification, private $iOSNotificationService: IiOSNotificationService, private $logger: ILogger) { } public async executeAttachRequest(device: Mobile.IiOSDevice, timeout: number, projectId: string): Promise { - let npc = new iOSProxyServices.NotificationProxyClient(device, this.$injector); let data = [this.$iOSNotification.getAlreadyConnected(projectId), this.$iOSNotification.getReadyForAttach(projectId), this.$iOSNotification.getAttachAvailable(projectId)] - .map((notification) => this.$iOSNotificationService.awaitNotification(npc, notification, timeout)), + .map((notification) => this.$iOSNotificationService.awaitNotification(device.deviceInfo.identifier, notification, timeout)), alreadyConnected = data[0], readyForAttach = data[1], attachAvailable = data[2]; - npc.postNotificationAndAttachForData(this.$iOSNotification.getAttachAvailabilityQuery(projectId)); + await this.$iOSNotificationService.postNotification(device.deviceInfo.identifier, this.$iOSNotification.getAttachAvailabilityQuery(projectId)); let receivedNotification: string; try { @@ -30,37 +26,39 @@ export class IOSSocketRequestExecutor implements IiOSSocketRequestExecutor { this.$errors.failWithoutHelp("A client is already connected."); break; case this.$iOSNotification.getAttachAvailable(projectId): - await this.executeAttachAvailable(npc, timeout, projectId); + await this.executeAttachAvailable(device.deviceInfo.identifier, timeout); break; case this.$iOSNotification.getReadyForAttach(projectId): break; } } - public async executeLaunchRequest(device: Mobile.IiOSDevice, timeout: number, readyForAttachTimeout: number, projectId: string, shouldBreak?: boolean): Promise { - let npc = new iOSProxyServices.NotificationProxyClient(device, this.$injector); - + public async executeLaunchRequest(deviceIdentifier: string, timeout: number, readyForAttachTimeout: number, shouldBreak?: boolean): Promise { try { - await this.$iOSNotificationService.awaitNotification(npc, this.$iOSNotification.getAppLaunching(projectId), timeout); - process.nextTick(() => { + await this.$iOSNotificationService.awaitNotification(deviceIdentifier, this.$iOSNotification.appLaunching, timeout); if (shouldBreak) { - npc.postNotificationAndAttachForData(this.$iOSNotification.getWaitForDebug(projectId)); - } + await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.waitForDebug); + } - npc.postNotificationAndAttachForData(this.$iOSNotification.getAttachRequest(projectId)); - }); + // We need to send the ObserveNotification ReadyForAttach before we post the AttachRequest. + const readyForAttachPromise = this.$iOSNotificationService.awaitNotification(deviceIdentifier, this.$iOSNotification.readyForAttach, readyForAttachTimeout); - await this.$iOSNotificationService.awaitNotification(npc, this.$iOSNotification.getReadyForAttach(projectId), readyForAttachTimeout); + await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.attachRequest); + await readyForAttachPromise; } catch (e) { - this.$logger.trace(`Timeout error: ${e}`); - this.$errors.failWithoutHelp("Timeout waiting for response from NativeScript runtime."); + this.$logger.trace("Launch request error:"); + this.$logger.trace(e); + this.$errors.failWithoutHelp("Error while waiting for response from NativeScript runtime."); } } - private async executeAttachAvailable(npc: Mobile.INotificationProxyClient, timeout: number, projectId: string): Promise { - process.nextTick(() => npc.postNotificationAndAttachForData(this.$iOSNotification.getAttachRequest(projectId))); + private async executeAttachAvailable(deviceIdentifier: string, timeout: number): Promise { try { - await this.$iOSNotificationService.awaitNotification(npc, this.$iOSNotification.getReadyForAttach(projectId), timeout); + // We should create this promise here because we need to send the ObserveNotification on the device + // before we send the PostNotification. + const readyForAttachPromise = this.$iOSNotificationService.awaitNotification(deviceIdentifier, this.$iOSNotification.readyForAttach, timeout); + await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.attachRequest); + await readyForAttachPromise; } catch (e) { this.$errors.failWithoutHelp(`The application ${projectId} timed out when performing the socket handshake.`); } diff --git a/lib/services/ios-debug-service.ts b/lib/services/ios-debug-service.ts index d38c3392a1..6af986887d 100644 --- a/lib/services/ios-debug-service.ts +++ b/lib/services/ios-debug-service.ts @@ -158,8 +158,8 @@ class IOSDebugService implements IDebugService { private async debugBrkCore(device: Mobile.IiOSDevice, projectData: IProjectData, shouldBreak?: boolean): Promise { let timeout = this.$utils.getMilliSecondsTimeout(TIMEOUT_SECONDS); - await this.$iOSSocketRequestExecutor.executeLaunchRequest(device, timeout, timeout, projectData.projectId, shouldBreak); - await this.wireDebuggerClient(projectData, device); + await this.$iOSSocketRequestExecutor.executeLaunchRequest(device.deviceInfo.identifier, timeout, timeout, shouldBreak); + await this.wireDebuggerClient(device); } private async deviceStart(projectData: IProjectData): Promise { @@ -174,12 +174,15 @@ class IOSDebugService implements IDebugService { } private async wireDebuggerClient(projectData: IProjectData, device?: Mobile.IiOSDevice): Promise { - let factory = () => { - let socket = device ? device.connectToPort(inspectorBackendPort) : net.connect(inspectorBackendPort); + const factoryPromise = async () => { + let socket = device ? await device.connectToPort(inspectorBackendPort) : net.connect(inspectorBackendPort); this._sockets.push(socket); return socket; }; + const socket = await factoryPromise(); + const factory = () => socket; + if (this.$options.chrome) { this._socketProxy = this.$socketProxyFactory.createWebSocketProxy(factory); diff --git a/lib/services/ios-notification-service.ts b/lib/services/ios-notification-service.ts index 160d2f0112..79e77864e1 100644 --- a/lib/services/ios-notification-service.ts +++ b/lib/services/ios-notification-service.ts @@ -1,25 +1,25 @@ -export class IOSNotificationService implements IiOSNotificationService { - public async awaitNotification(npc: Mobile.INotificationProxyClient, notification: string, timeout: number): Promise { - return new Promise((resolve, reject) => { - - let timeoutToken = setTimeout(() => { - detachObserver(); - reject(new Error(`Timeout receiving ${notification} notification.`)); - }, timeout); +import * as constants from "../common/constants"; - function notificationObserver(_notification: string) { - clearTimeout(timeoutToken); - detachObserver(); - resolve(_notification); - } +export class IOSNotificationService implements IiOSNotificationService { + constructor(private $iosDeviceOperations: IIOSDeviceOperations) { } - function detachObserver() { - process.nextTick(() => npc.removeObserver(notification, notificationObserver)); - } + public async awaitNotification(deviceIdentifier: string, notification: string, timeout: number): Promise { + const notificationResponse = await this.$iosDeviceOperations.notify([{ + deviceId: deviceIdentifier, + commandType: constants.IOS_OBSERVE_NOTIFICATION_COMMAND_TYPE, + notificationName: notification, + shouldWaitForResponse: true, + timeout: timeout, + responseCommandType: constants.IOS_RELAY_NOTIFICATION_COMMAND_TYPE, + responsePropertyName: "Name" + }]); - npc.addObserver(notification, notificationObserver); + return _.first(notificationResponse[deviceIdentifier]).response; + } - }); + public async postNotification(deviceIdentifier: string, notification: string): Promise { + await this.$iosDeviceOperations.notify([{ deviceId: deviceIdentifier, commandType: constants.IOS_POST_NOTIFICATION_COMMAND_TYPE, notificationName: notification, shouldWaitForResponse: false }]); } } + $injector.register("iOSNotificationService", IOSNotificationService); diff --git a/lib/services/livesync/ios-device-livesync-service.ts b/lib/services/livesync/ios-device-livesync-service.ts index 1ba5c6ae7a..705c2ab854 100644 --- a/lib/services/livesync/ios-device-livesync-service.ts +++ b/lib/services/livesync/ios-device-livesync-service.ts @@ -10,11 +10,10 @@ class IOSLiveSyncService implements INativeScriptDeviceLiveSyncService { private socket: net.Socket; private device: Mobile.IiOSDevice; - constructor(_device: Mobile.IDevice, + constructor(_device: Mobile.IiOSDevice, private $iOSSocketRequestExecutor: IiOSSocketRequestExecutor, private $iOSNotification: IiOSNotification, private $iOSEmulatorServices: Mobile.IiOSSimulatorService, - private $injector: IInjector, private $logger: ILogger, private $options: IOptions, private $iOSDebugService: IDebugService, @@ -22,7 +21,7 @@ class IOSLiveSyncService implements INativeScriptDeviceLiveSyncService { private $liveSyncProvider: ILiveSyncProvider, private $processService: IProcessService) { - this.device = (_device); + this.device = _device; } public get debugService(): IDebugService { @@ -49,7 +48,7 @@ class IOSLiveSyncService implements INativeScriptDeviceLiveSyncService { } else { let timeout = 9000; await this.$iOSSocketRequestExecutor.executeAttachRequest(this.device, timeout, projectId); - this.socket = this.device.connectToPort(IOSLiveSyncService.BACKEND_PORT); + this.socket = await this.device.connectToPort(IOSLiveSyncService.BACKEND_PORT); } this.attachEventHandlers(); @@ -88,8 +87,7 @@ class IOSLiveSyncService implements INativeScriptDeviceLiveSyncService { } private async restartApplication(deviceAppData: Mobile.IDeviceAppData): Promise { - let projectData: IProjectData = this.$injector.resolve("projectData"); - return this.device.applicationManager.restartApplication(deviceAppData.appIdentifier, projectData.projectName); + return this.device.applicationManager.restartApplication(deviceAppData.appIdentifier); } private async reloadPage(deviceAppData: Mobile.IDeviceAppData, localToDevicePaths: Mobile.ILocalToDevicePathData[]): Promise { diff --git a/package.json b/package.json index d9fdc42b36..77af27cf8a 100644 --- a/package.json +++ b/package.json @@ -37,12 +37,12 @@ "colors": "1.1.2", "email-validator": "1.0.4", "esprima": "2.7.0", - "ffi": "https://github.com/icenium/node-ffi/tarball/v2.0.0.5", "filesize": "3.1.2", "gaze": "1.1.0", "glob": "^7.0.3", "iconv-lite": "0.4.11", "inquirer": "0.9.0", + "ios-device-lib": "0.1.0", "ios-mobileprovision-finder": "1.0.9", "ios-sim-portable": "~2.0.0", "lockfile": "1.0.1", @@ -62,8 +62,6 @@ "plistlib": "0.2.1", "progress-stream": "1.1.1", "properties-parser": "0.2.3", - "ref": "https://github.com/icenium/ref/tarball/v1.3.2.3", - "ref-struct": "https://github.com/telerik/ref-struct/tarball/v1.0.2.5", "semver": "5.0.1", "shelljs": "0.7.6", "source-map": "0.5.6", diff --git a/test/ios-project-service.ts b/test/ios-project-service.ts index 979760468e..a3db290294 100644 --- a/test/ios-project-service.ts +++ b/test/ios-project-service.ts @@ -79,6 +79,7 @@ function createTestInjector(projectPath: string, projectName: string): IInjector testInjector.register("utils", Utils); testInjector.register("iTunesValidator", {}); testInjector.register("xcprojService", {}); + testInjector.register("iosDeviceOperations", {}); testInjector.register("pluginVariablesService", PluginVariablesService); testInjector.register("pluginVariablesHelper", PluginVariablesHelper); testInjector.register("androidProcessService", {}); From 7e1f1bd74f73e6cd7f50c8bbce0617672fd56c8a Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Thu, 2 Mar 2017 14:16:15 +0200 Subject: [PATCH 2/8] Change the notification logic --- lib/declarations.ts | 5 +-- .../ios/socket-request-executor.ts | 35 ++++++++++++------- lib/services/ios-debug-service.ts | 7 +++- lib/services/ios-notification-service.ts | 23 ++++++++---- 4 files changed, 47 insertions(+), 23 deletions(-) diff --git a/lib/declarations.ts b/lib/declarations.ts index 66847acd53..08a508d18a 100644 --- a/lib/declarations.ts +++ b/lib/declarations.ts @@ -304,8 +304,9 @@ interface IiOSNotification { } interface IiOSNotificationService { - awaitNotification(deviceIdentifier: string, notification: string, timeout: number): Promise; - postNotification(deviceIdentifier: string, notification: string): Promise; + awaitNotification(deviceIdentifier: string, socket: number, timeout: number): Promise; + postNotification(deviceIdentifier: string, notification: string, commandType?: string): Promise; + subscribeForNotification(deviceIdentifier: string, notification: string, timeout: number): Promise>; } interface IiOSSocketRequestExecutor { diff --git a/lib/device-sockets/ios/socket-request-executor.ts b/lib/device-sockets/ios/socket-request-executor.ts index 0e57efd372..82145124fd 100644 --- a/lib/device-sockets/ios/socket-request-executor.ts +++ b/lib/device-sockets/ios/socket-request-executor.ts @@ -1,3 +1,5 @@ +import * as constants from "../../common/constants"; + export class IOSSocketRequestExecutor implements IiOSSocketRequestExecutor { constructor(private $errors: IErrors, private $iOSNotification: IiOSNotification, @@ -5,18 +7,20 @@ export class IOSSocketRequestExecutor implements IiOSSocketRequestExecutor { private $logger: ILogger) { } public async executeAttachRequest(device: Mobile.IiOSDevice, timeout: number, projectId: string): Promise { + const deviceIdentifier = device.deviceInfo.identifier; - let data = [this.$iOSNotification.getAlreadyConnected(projectId), this.$iOSNotification.getReadyForAttach(projectId), this.$iOSNotification.getAttachAvailable(projectId)] - .map((notification) => this.$iOSNotificationService.awaitNotification(device.deviceInfo.identifier, notification, timeout)), - alreadyConnected = data[0], - readyForAttach = data[1], - attachAvailable = data[2]; + const observeNotificationPromises = [ + await this.$iOSNotificationService.subscribeForNotification(deviceIdentifier, this.$iOSNotification.alreadyConnected, timeout), + await this.$iOSNotificationService.subscribeForNotification(deviceIdentifier, this.$iOSNotification.readyForAttach, timeout), + await this.$iOSNotificationService.subscribeForNotification(deviceIdentifier, this.$iOSNotification.attachAvailable, timeout) + ]; - await this.$iOSNotificationService.postNotification(device.deviceInfo.identifier, this.$iOSNotification.getAttachAvailabilityQuery(projectId)); + // Trigger the notifications update. + await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.attachAvailabilityQuery, constants.IOS_POST_NOTIFICATION_COMMAND_TYPE); let receivedNotification: string; try { - receivedNotification = await Promise.race([alreadyConnected, readyForAttach, attachAvailable]); + receivedNotification = await Promise.race(observeNotificationPromises); } catch (e) { this.$errors.failWithoutHelp(`The application ${projectId} does not appear to be running on ${device.deviceInfo.displayName} or is not built with debugging enabled.`); } @@ -26,24 +30,29 @@ export class IOSSocketRequestExecutor implements IiOSSocketRequestExecutor { this.$errors.failWithoutHelp("A client is already connected."); break; case this.$iOSNotification.getAttachAvailable(projectId): - await this.executeAttachAvailable(device.deviceInfo.identifier, timeout); + await this.executeAttachAvailable(deviceIdentifier, timeout); break; case this.$iOSNotification.getReadyForAttach(projectId): break; + default: + this.$logger.trace("Response from attach availability query:"); + this.$logger.trace(receivedNotification); + this.$errors.failWithoutHelp("No notification received while executing attach request."); } } public async executeLaunchRequest(deviceIdentifier: string, timeout: number, readyForAttachTimeout: number, shouldBreak?: boolean): Promise { try { - await this.$iOSNotificationService.awaitNotification(deviceIdentifier, this.$iOSNotification.appLaunching, timeout); + const appLaunchingPromise = await this.$iOSNotificationService.subscribeForNotification(deviceIdentifier, this.$iOSNotification.appLaunching, timeout); + await appLaunchingPromise; if (shouldBreak) { - await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.waitForDebug); + await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.waitForDebug, constants.IOS_POST_NOTIFICATION_COMMAND_TYPE); } // We need to send the ObserveNotification ReadyForAttach before we post the AttachRequest. - const readyForAttachPromise = this.$iOSNotificationService.awaitNotification(deviceIdentifier, this.$iOSNotification.readyForAttach, readyForAttachTimeout); + const readyForAttachPromise = await this.$iOSNotificationService.subscribeForNotification(deviceIdentifier, this.$iOSNotification.readyForAttach, readyForAttachTimeout); - await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.attachRequest); + await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.attachRequest, constants.IOS_POST_NOTIFICATION_COMMAND_TYPE); await readyForAttachPromise; } catch (e) { this.$logger.trace("Launch request error:"); @@ -56,7 +65,7 @@ export class IOSSocketRequestExecutor implements IiOSSocketRequestExecutor { try { // We should create this promise here because we need to send the ObserveNotification on the device // before we send the PostNotification. - const readyForAttachPromise = this.$iOSNotificationService.awaitNotification(deviceIdentifier, this.$iOSNotification.readyForAttach, timeout); + const readyForAttachPromise = await this.$iOSNotificationService.subscribeForNotification(deviceIdentifier, this.$iOSNotification.readyForAttach, timeout); await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.attachRequest); await readyForAttachPromise; } catch (e) { diff --git a/lib/services/ios-debug-service.ts b/lib/services/ios-debug-service.ts index 6af986887d..75b54282d2 100644 --- a/lib/services/ios-debug-service.ts +++ b/lib/services/ios-debug-service.ts @@ -181,7 +181,12 @@ class IOSDebugService implements IDebugService { }; const socket = await factoryPromise(); - const factory = () => socket; + const factory = () => { + process.nextTick(() => { + socket.emit("connect"); + }); + return socket; + }; if (this.$options.chrome) { this._socketProxy = this.$socketProxyFactory.createWebSocketProxy(factory); diff --git a/lib/services/ios-notification-service.ts b/lib/services/ios-notification-service.ts index 79e77864e1..0a8f7834d4 100644 --- a/lib/services/ios-notification-service.ts +++ b/lib/services/ios-notification-service.ts @@ -3,12 +3,10 @@ import * as constants from "../common/constants"; export class IOSNotificationService implements IiOSNotificationService { constructor(private $iosDeviceOperations: IIOSDeviceOperations) { } - public async awaitNotification(deviceIdentifier: string, notification: string, timeout: number): Promise { - const notificationResponse = await this.$iosDeviceOperations.notify([{ + public async awaitNotification(deviceIdentifier: string, socket: number, timeout: number): Promise { + const notificationResponse = await this.$iosDeviceOperations.awaitNotificationResponse([{ deviceId: deviceIdentifier, - commandType: constants.IOS_OBSERVE_NOTIFICATION_COMMAND_TYPE, - notificationName: notification, - shouldWaitForResponse: true, + socket: socket, timeout: timeout, responseCommandType: constants.IOS_RELAY_NOTIFICATION_COMMAND_TYPE, responsePropertyName: "Name" @@ -17,8 +15,19 @@ export class IOSNotificationService implements IiOSNotificationService { return _.first(notificationResponse[deviceIdentifier]).response; } - public async postNotification(deviceIdentifier: string, notification: string): Promise { - await this.$iosDeviceOperations.notify([{ deviceId: deviceIdentifier, commandType: constants.IOS_POST_NOTIFICATION_COMMAND_TYPE, notificationName: notification, shouldWaitForResponse: false }]); + public subscribeForNotification(deviceIdentifier: string, notification: string, timeout: number): Promise> { + return new Promise((resolve, reject) => { + this.postNotification(deviceIdentifier, notification, constants.IOS_OBSERVE_NOTIFICATION_COMMAND_TYPE) + .then((socket) => { + resolve(this.awaitNotification(deviceIdentifier, +socket, timeout)); + }); + }); + } + + public async postNotification(deviceIdentifier: string, notification: string, commandType?: string): Promise { + commandType = commandType || constants.IOS_POST_NOTIFICATION_COMMAND_TYPE; + const response = await this.$iosDeviceOperations.postNotification([{ deviceId: deviceIdentifier, commandType: commandType, notificationName: notification }]); + return _.first(response[deviceIdentifier]).response; } } From 3eb893a21b2dbcf45ae4be3d073baf92d4d400a9 Mon Sep 17 00:00:00 2001 From: Dimitar Kerezov Date: Fri, 3 Mar 2017 15:09:37 +0200 Subject: [PATCH 3/8] Post-rebase fixes --- lib/common | 2 +- lib/declarations.ts | 2 +- .../ios/socket-request-executor.ts | 26 +++++++++---------- lib/services/ios-debug-service.ts | 4 +-- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/lib/common b/lib/common index 24d47bbdf7..741a91d6b5 160000 --- a/lib/common +++ b/lib/common @@ -1 +1 @@ -Subproject commit 24d47bbdf7c794a575ad8ac950fa75e9c7a1784f +Subproject commit 741a91d6b58876a26f0351d7ddc5826123ce36d5 diff --git a/lib/declarations.ts b/lib/declarations.ts index 08a508d18a..75aee850cd 100644 --- a/lib/declarations.ts +++ b/lib/declarations.ts @@ -310,7 +310,7 @@ interface IiOSNotificationService { } interface IiOSSocketRequestExecutor { - executeLaunchRequest(device: Mobile.IiOSDevice, timeout: number, readyForAttachTimeout: number, projectId: string, shouldBreak?: boolean): Promise; + executeLaunchRequest(deviceIdentifier: string, timeout: number, readyForAttachTimeout: number, projectId: string, shouldBreak?: boolean): Promise; executeAttachRequest(device: Mobile.IiOSDevice, timeout: number, projectId: string): Promise; } diff --git a/lib/device-sockets/ios/socket-request-executor.ts b/lib/device-sockets/ios/socket-request-executor.ts index 82145124fd..4111427e4a 100644 --- a/lib/device-sockets/ios/socket-request-executor.ts +++ b/lib/device-sockets/ios/socket-request-executor.ts @@ -10,13 +10,13 @@ export class IOSSocketRequestExecutor implements IiOSSocketRequestExecutor { const deviceIdentifier = device.deviceInfo.identifier; const observeNotificationPromises = [ - await this.$iOSNotificationService.subscribeForNotification(deviceIdentifier, this.$iOSNotification.alreadyConnected, timeout), - await this.$iOSNotificationService.subscribeForNotification(deviceIdentifier, this.$iOSNotification.readyForAttach, timeout), - await this.$iOSNotificationService.subscribeForNotification(deviceIdentifier, this.$iOSNotification.attachAvailable, timeout) + await this.$iOSNotificationService.subscribeForNotification(deviceIdentifier, this.$iOSNotification.getAlreadyConnected(projectId), timeout), + await this.$iOSNotificationService.subscribeForNotification(deviceIdentifier, this.$iOSNotification.getReadyForAttach(projectId), timeout), + await this.$iOSNotificationService.subscribeForNotification(deviceIdentifier, this.$iOSNotification.getAttachAvailable(projectId), timeout) ]; // Trigger the notifications update. - await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.attachAvailabilityQuery, constants.IOS_POST_NOTIFICATION_COMMAND_TYPE); + await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.getAttachAvailabilityQuery(projectId), constants.IOS_POST_NOTIFICATION_COMMAND_TYPE); let receivedNotification: string; try { @@ -30,7 +30,7 @@ export class IOSSocketRequestExecutor implements IiOSSocketRequestExecutor { this.$errors.failWithoutHelp("A client is already connected."); break; case this.$iOSNotification.getAttachAvailable(projectId): - await this.executeAttachAvailable(deviceIdentifier, timeout); + await this.executeAttachAvailable(deviceIdentifier, projectId, timeout); break; case this.$iOSNotification.getReadyForAttach(projectId): break; @@ -41,18 +41,18 @@ export class IOSSocketRequestExecutor implements IiOSSocketRequestExecutor { } } - public async executeLaunchRequest(deviceIdentifier: string, timeout: number, readyForAttachTimeout: number, shouldBreak?: boolean): Promise { + public async executeLaunchRequest(deviceIdentifier: string, timeout: number, readyForAttachTimeout: number, projectId: string, shouldBreak?: boolean): Promise { try { - const appLaunchingPromise = await this.$iOSNotificationService.subscribeForNotification(deviceIdentifier, this.$iOSNotification.appLaunching, timeout); + const appLaunchingPromise = await this.$iOSNotificationService.subscribeForNotification(deviceIdentifier, this.$iOSNotification.getAppLaunching(projectId), timeout); await appLaunchingPromise; if (shouldBreak) { - await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.waitForDebug, constants.IOS_POST_NOTIFICATION_COMMAND_TYPE); + await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.getWaitForDebug(projectId), constants.IOS_POST_NOTIFICATION_COMMAND_TYPE); } // We need to send the ObserveNotification ReadyForAttach before we post the AttachRequest. - const readyForAttachPromise = await this.$iOSNotificationService.subscribeForNotification(deviceIdentifier, this.$iOSNotification.readyForAttach, readyForAttachTimeout); + const readyForAttachPromise = await this.$iOSNotificationService.subscribeForNotification(deviceIdentifier, this.$iOSNotification.getReadyForAttach(projectId), readyForAttachTimeout); - await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.attachRequest, constants.IOS_POST_NOTIFICATION_COMMAND_TYPE); + await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.getAttachRequest(projectId), constants.IOS_POST_NOTIFICATION_COMMAND_TYPE); await readyForAttachPromise; } catch (e) { this.$logger.trace("Launch request error:"); @@ -61,12 +61,12 @@ export class IOSSocketRequestExecutor implements IiOSSocketRequestExecutor { } } - private async executeAttachAvailable(deviceIdentifier: string, timeout: number): Promise { + private async executeAttachAvailable(deviceIdentifier: string, projectId: string, timeout: number): Promise { try { // We should create this promise here because we need to send the ObserveNotification on the device // before we send the PostNotification. - const readyForAttachPromise = await this.$iOSNotificationService.subscribeForNotification(deviceIdentifier, this.$iOSNotification.readyForAttach, timeout); - await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.attachRequest); + const readyForAttachPromise = await this.$iOSNotificationService.subscribeForNotification(deviceIdentifier, this.$iOSNotification.getReadyForAttach(projectId), timeout); + await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.getAttachRequest(projectId)); await readyForAttachPromise; } catch (e) { this.$errors.failWithoutHelp(`The application ${projectId} timed out when performing the socket handshake.`); diff --git a/lib/services/ios-debug-service.ts b/lib/services/ios-debug-service.ts index 75b54282d2..3a14189884 100644 --- a/lib/services/ios-debug-service.ts +++ b/lib/services/ios-debug-service.ts @@ -158,8 +158,8 @@ class IOSDebugService implements IDebugService { private async debugBrkCore(device: Mobile.IiOSDevice, projectData: IProjectData, shouldBreak?: boolean): Promise { let timeout = this.$utils.getMilliSecondsTimeout(TIMEOUT_SECONDS); - await this.$iOSSocketRequestExecutor.executeLaunchRequest(device.deviceInfo.identifier, timeout, timeout, shouldBreak); - await this.wireDebuggerClient(device); + await this.$iOSSocketRequestExecutor.executeLaunchRequest(device.deviceInfo.identifier, timeout, timeout, projectData.projectId, shouldBreak); + await this.wireDebuggerClient(projectData, device); } private async deviceStart(projectData: IProjectData): Promise { From 0890acbf529c704d7cb08fae3d7166eb98c61188 Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Mon, 6 Mar 2017 15:33:10 +0200 Subject: [PATCH 4/8] Add receive message from ios device socket logic --- lib/common | 2 +- lib/declarations.ts | 1 - .../ios/socket-proxy-factory.ts | 11 +++--- .../ios/socket-request-executor.ts | 35 ++++++++++++------- lib/services/ios-notification-service.ts | 9 ----- 5 files changed, 29 insertions(+), 29 deletions(-) diff --git a/lib/common b/lib/common index 741a91d6b5..6fd98a6656 160000 --- a/lib/common +++ b/lib/common @@ -1 +1 @@ -Subproject commit 741a91d6b58876a26f0351d7ddc5826123ce36d5 +Subproject commit 6fd98a66569fa47768fc7cea1978591bfe9fd068 diff --git a/lib/declarations.ts b/lib/declarations.ts index 75aee850cd..0af4a2f5b2 100644 --- a/lib/declarations.ts +++ b/lib/declarations.ts @@ -306,7 +306,6 @@ interface IiOSNotification { interface IiOSNotificationService { awaitNotification(deviceIdentifier: string, socket: number, timeout: number): Promise; postNotification(deviceIdentifier: string, notification: string, commandType?: string): Promise; - subscribeForNotification(deviceIdentifier: string, notification: string, timeout: number): Promise>; } interface IiOSSocketRequestExecutor { diff --git a/lib/device-sockets/ios/socket-proxy-factory.ts b/lib/device-sockets/ios/socket-proxy-factory.ts index 7c720fab88..711c83f78c 100644 --- a/lib/device-sockets/ios/socket-proxy-factory.ts +++ b/lib/device-sockets/ios/socket-proxy-factory.ts @@ -66,8 +66,8 @@ export class SocketProxyFactory implements ISocketProxyFactory { return server; } - public createWebSocketProxy(factory: () => net.Socket): ws.Server { - let socketFactory = (callback: (_socket: net.Socket) => void) => helpers.connectEventually(factory, callback); + public createWebSocketProxy(factory: () => Promise): ws.Server { + let socketFactory = async (callback: (_socket: net.Socket) => void) => callback(await factory()); // NOTE: We will try to provide command line options to select ports, at least on the localhost. let localPort = 8080; @@ -102,10 +102,9 @@ export class SocketProxyFactory implements ISocketProxyFactory { webSocket.on("message", (message, flags) => { let length = Buffer.byteLength(message, encoding); - let payload = new Buffer(length + 4); - payload.writeInt32BE(length, 0); - payload.write(message, 4, length, encoding); - deviceSocket.write(payload); + let payload = new Buffer(length); + payload.write(message, 0, length, encoding); + deviceSocket.write(payload.toString()); }); deviceSocket.on("end", () => { diff --git a/lib/device-sockets/ios/socket-request-executor.ts b/lib/device-sockets/ios/socket-request-executor.ts index 4111427e4a..4fff2ae303 100644 --- a/lib/device-sockets/ios/socket-request-executor.ts +++ b/lib/device-sockets/ios/socket-request-executor.ts @@ -4,19 +4,27 @@ export class IOSSocketRequestExecutor implements IiOSSocketRequestExecutor { constructor(private $errors: IErrors, private $iOSNotification: IiOSNotification, private $iOSNotificationService: IiOSNotificationService, - private $logger: ILogger) { } + private $logger: ILogger, + private $projectData: IProjectData, + private $iosDeviceOperations: IIOSDeviceOperations) { + this.$iosDeviceOperations.setShouldDispose(false); + } public async executeAttachRequest(device: Mobile.IiOSDevice, timeout: number, projectId: string): Promise { const deviceIdentifier = device.deviceInfo.identifier; - const observeNotificationPromises = [ - await this.$iOSNotificationService.subscribeForNotification(deviceIdentifier, this.$iOSNotification.getAlreadyConnected(projectId), timeout), - await this.$iOSNotificationService.subscribeForNotification(deviceIdentifier, this.$iOSNotification.getReadyForAttach(projectId), timeout), - await this.$iOSNotificationService.subscribeForNotification(deviceIdentifier, this.$iOSNotification.getAttachAvailable(projectId), timeout) + const observeNotificationSockets = [ + await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.alreadyConnected, constants.IOS_OBSERVE_NOTIFICATION_COMMAND_TYPE), + await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.readyForAttach, constants.IOS_OBSERVE_NOTIFICATION_COMMAND_TYPE), + await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.attachAvailable, constants.IOS_OBSERVE_NOTIFICATION_COMMAND_TYPE) ]; + const observeNotificationPromises = _.map(observeNotificationSockets, s => { + return this.$iOSNotificationService.awaitNotification(deviceIdentifier, +s, timeout); + }); + // Trigger the notifications update. - await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.getAttachAvailabilityQuery(projectId), constants.IOS_POST_NOTIFICATION_COMMAND_TYPE); + await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.attachAvailabilityQuery); let receivedNotification: string; try { @@ -43,16 +51,18 @@ export class IOSSocketRequestExecutor implements IiOSSocketRequestExecutor { public async executeLaunchRequest(deviceIdentifier: string, timeout: number, readyForAttachTimeout: number, projectId: string, shouldBreak?: boolean): Promise { try { - const appLaunchingPromise = await this.$iOSNotificationService.subscribeForNotification(deviceIdentifier, this.$iOSNotification.getAppLaunching(projectId), timeout); - await appLaunchingPromise; + const appLaunchingSocket = await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.appLaunching, constants.IOS_OBSERVE_NOTIFICATION_COMMAND_TYPE); + await this.$iOSNotificationService.awaitNotification(deviceIdentifier, +appLaunchingSocket, timeout); + if (shouldBreak) { await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.getWaitForDebug(projectId), constants.IOS_POST_NOTIFICATION_COMMAND_TYPE); } // We need to send the ObserveNotification ReadyForAttach before we post the AttachRequest. - const readyForAttachPromise = await this.$iOSNotificationService.subscribeForNotification(deviceIdentifier, this.$iOSNotification.getReadyForAttach(projectId), readyForAttachTimeout); + const readyForAttachSocket = await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.readyForAttach, constants.IOS_OBSERVE_NOTIFICATION_COMMAND_TYPE); + const readyForAttachPromise = this.$iOSNotificationService.awaitNotification(deviceIdentifier, +readyForAttachSocket, readyForAttachTimeout); - await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.getAttachRequest(projectId), constants.IOS_POST_NOTIFICATION_COMMAND_TYPE); + await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.attachRequest); await readyForAttachPromise; } catch (e) { this.$logger.trace("Launch request error:"); @@ -65,8 +75,9 @@ export class IOSSocketRequestExecutor implements IiOSSocketRequestExecutor { try { // We should create this promise here because we need to send the ObserveNotification on the device // before we send the PostNotification. - const readyForAttachPromise = await this.$iOSNotificationService.subscribeForNotification(deviceIdentifier, this.$iOSNotification.getReadyForAttach(projectId), timeout); - await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.getAttachRequest(projectId)); + const readyForAttachSocket = await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.readyForAttach, constants.IOS_OBSERVE_NOTIFICATION_COMMAND_TYPE); + const readyForAttachPromise = this.$iOSNotificationService.awaitNotification(deviceIdentifier, +readyForAttachSocket, timeout); + await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.attachRequest); await readyForAttachPromise; } catch (e) { this.$errors.failWithoutHelp(`The application ${projectId} timed out when performing the socket handshake.`); diff --git a/lib/services/ios-notification-service.ts b/lib/services/ios-notification-service.ts index 0a8f7834d4..36b8f6dc87 100644 --- a/lib/services/ios-notification-service.ts +++ b/lib/services/ios-notification-service.ts @@ -15,15 +15,6 @@ export class IOSNotificationService implements IiOSNotificationService { return _.first(notificationResponse[deviceIdentifier]).response; } - public subscribeForNotification(deviceIdentifier: string, notification: string, timeout: number): Promise> { - return new Promise((resolve, reject) => { - this.postNotification(deviceIdentifier, notification, constants.IOS_OBSERVE_NOTIFICATION_COMMAND_TYPE) - .then((socket) => { - resolve(this.awaitNotification(deviceIdentifier, +socket, timeout)); - }); - }); - } - public async postNotification(deviceIdentifier: string, notification: string, commandType?: string): Promise { commandType = commandType || constants.IOS_POST_NOTIFICATION_COMMAND_TYPE; const response = await this.$iosDeviceOperations.postNotification([{ deviceId: deviceIdentifier, commandType: commandType, notificationName: notification }]); From c5e98bdc0e4086e6f4b2662a1f2a84402a446d52 Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Mon, 6 Mar 2017 15:50:37 +0200 Subject: [PATCH 5/8] Fix rebase issues --- .../ios/socket-request-executor.ts | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/lib/device-sockets/ios/socket-request-executor.ts b/lib/device-sockets/ios/socket-request-executor.ts index 4fff2ae303..61d06e5f05 100644 --- a/lib/device-sockets/ios/socket-request-executor.ts +++ b/lib/device-sockets/ios/socket-request-executor.ts @@ -5,18 +5,17 @@ export class IOSSocketRequestExecutor implements IiOSSocketRequestExecutor { private $iOSNotification: IiOSNotification, private $iOSNotificationService: IiOSNotificationService, private $logger: ILogger, - private $projectData: IProjectData, - private $iosDeviceOperations: IIOSDeviceOperations) { - this.$iosDeviceOperations.setShouldDispose(false); - } + private $iosDeviceOperations: IIOSDeviceOperations) { + this.$iosDeviceOperations.setShouldDispose(false); + } public async executeAttachRequest(device: Mobile.IiOSDevice, timeout: number, projectId: string): Promise { const deviceIdentifier = device.deviceInfo.identifier; const observeNotificationSockets = [ - await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.alreadyConnected, constants.IOS_OBSERVE_NOTIFICATION_COMMAND_TYPE), - await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.readyForAttach, constants.IOS_OBSERVE_NOTIFICATION_COMMAND_TYPE), - await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.attachAvailable, constants.IOS_OBSERVE_NOTIFICATION_COMMAND_TYPE) + await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.getAlreadyConnected(projectId), constants.IOS_OBSERVE_NOTIFICATION_COMMAND_TYPE), + await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.getReadyForAttach(projectId), constants.IOS_OBSERVE_NOTIFICATION_COMMAND_TYPE), + await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.getAttachAvailable(projectId), constants.IOS_OBSERVE_NOTIFICATION_COMMAND_TYPE) ]; const observeNotificationPromises = _.map(observeNotificationSockets, s => { @@ -24,7 +23,7 @@ export class IOSSocketRequestExecutor implements IiOSSocketRequestExecutor { }); // Trigger the notifications update. - await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.attachAvailabilityQuery); + await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.getAttachAvailabilityQuery(projectId)); let receivedNotification: string; try { @@ -51,18 +50,18 @@ export class IOSSocketRequestExecutor implements IiOSSocketRequestExecutor { public async executeLaunchRequest(deviceIdentifier: string, timeout: number, readyForAttachTimeout: number, projectId: string, shouldBreak?: boolean): Promise { try { - const appLaunchingSocket = await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.appLaunching, constants.IOS_OBSERVE_NOTIFICATION_COMMAND_TYPE); + const appLaunchingSocket = await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.getAppLaunching(projectId), constants.IOS_OBSERVE_NOTIFICATION_COMMAND_TYPE); await this.$iOSNotificationService.awaitNotification(deviceIdentifier, +appLaunchingSocket, timeout); - if (shouldBreak) { + if (shouldBreak) { await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.getWaitForDebug(projectId), constants.IOS_POST_NOTIFICATION_COMMAND_TYPE); } // We need to send the ObserveNotification ReadyForAttach before we post the AttachRequest. - const readyForAttachSocket = await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.readyForAttach, constants.IOS_OBSERVE_NOTIFICATION_COMMAND_TYPE); + const readyForAttachSocket = await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.getReadyForAttach(projectId), constants.IOS_OBSERVE_NOTIFICATION_COMMAND_TYPE); const readyForAttachPromise = this.$iOSNotificationService.awaitNotification(deviceIdentifier, +readyForAttachSocket, readyForAttachTimeout); - await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.attachRequest); + await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.getAttachRequest(projectId)); await readyForAttachPromise; } catch (e) { this.$logger.trace("Launch request error:"); @@ -75,9 +74,9 @@ export class IOSSocketRequestExecutor implements IiOSSocketRequestExecutor { try { // We should create this promise here because we need to send the ObserveNotification on the device // before we send the PostNotification. - const readyForAttachSocket = await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.readyForAttach, constants.IOS_OBSERVE_NOTIFICATION_COMMAND_TYPE); + const readyForAttachSocket = await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.getReadyForAttach(projectId), constants.IOS_OBSERVE_NOTIFICATION_COMMAND_TYPE); const readyForAttachPromise = this.$iOSNotificationService.awaitNotification(deviceIdentifier, +readyForAttachSocket, timeout); - await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.attachRequest); + await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.getAttachRequest(projectId)); await readyForAttachPromise; } catch (e) { this.$errors.failWithoutHelp(`The application ${projectId} timed out when performing the socket handshake.`); From ec5e7c7aac830febf70bae13a91dac1ee254cf17 Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Mon, 6 Mar 2017 16:14:00 +0200 Subject: [PATCH 6/8] WIP --- lib/device-sockets/ios/socket-request-executor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/device-sockets/ios/socket-request-executor.ts b/lib/device-sockets/ios/socket-request-executor.ts index 61d06e5f05..af14dfe13c 100644 --- a/lib/device-sockets/ios/socket-request-executor.ts +++ b/lib/device-sockets/ios/socket-request-executor.ts @@ -54,7 +54,7 @@ export class IOSSocketRequestExecutor implements IiOSSocketRequestExecutor { await this.$iOSNotificationService.awaitNotification(deviceIdentifier, +appLaunchingSocket, timeout); if (shouldBreak) { - await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.getWaitForDebug(projectId), constants.IOS_POST_NOTIFICATION_COMMAND_TYPE); + await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.getWaitForDebug(projectId)); } // We need to send the ObserveNotification ReadyForAttach before we post the AttachRequest. From c9d03b15b859b74f118c77e8ae7ae7cfe072a614 Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Thu, 9 Mar 2017 21:45:25 +0200 Subject: [PATCH 7/8] Fix tns debug ios issues Since we use the ios-device-lib to connect to the device backend port for debugging, the socket returned from the device can be used only in the ios-device lib. That's why we need to change the logic for creating the Node.js socket in the CLI. The ios-device-lib will expose the device socket on a specific port in the localhost. After we connect to the exposed socket we can continue to work like we used to. --- lib/common | 2 +- lib/declarations.ts | 2 +- .../ios/socket-proxy-factory.ts | 19 +++++++++---------- .../ios/socket-request-executor.ts | 9 ++++++--- lib/services/ios-debug-service.ts | 10 +--------- 5 files changed, 18 insertions(+), 24 deletions(-) diff --git a/lib/common b/lib/common index 6fd98a6656..cfd19f2eee 160000 --- a/lib/common +++ b/lib/common @@ -1 +1 @@ -Subproject commit 6fd98a66569fa47768fc7cea1978591bfe9fd068 +Subproject commit cfd19f2eee38ab92c869b14d3944ecfc8f521f71 diff --git a/lib/declarations.ts b/lib/declarations.ts index 0af4a2f5b2..4816d0f7a6 100644 --- a/lib/declarations.ts +++ b/lib/declarations.ts @@ -290,7 +290,7 @@ interface IAndroidToolsInfoData { interface ISocketProxyFactory { createTCPSocketProxy(factory: () => any): any; - createWebSocketProxy(factory: () => any): any; + createWebSocketProxy(factory: () => Promise): any; } interface IiOSNotification { diff --git a/lib/device-sockets/ios/socket-proxy-factory.ts b/lib/device-sockets/ios/socket-proxy-factory.ts index 711c83f78c..fd9883b04a 100644 --- a/lib/device-sockets/ios/socket-proxy-factory.ts +++ b/lib/device-sockets/ios/socket-proxy-factory.ts @@ -67,7 +67,6 @@ export class SocketProxyFactory implements ISocketProxyFactory { } public createWebSocketProxy(factory: () => Promise): ws.Server { - let socketFactory = async (callback: (_socket: net.Socket) => void) => callback(await factory()); // NOTE: We will try to provide command line options to select ports, at least on the localhost. let localPort = 8080; @@ -80,13 +79,12 @@ export class SocketProxyFactory implements ISocketProxyFactory { let server = new ws.Server({ port: localPort, - verifyClient: (info: any, callback: Function) => { + verifyClient: async (info: any, callback: Function) => { this.$logger.info("Frontend client connected."); - socketFactory((_socket: any) => { - this.$logger.info("Backend socket created."); - info.req["__deviceSocket"] = _socket; - callback(true); - }); + const _socket = await factory(); + this.$logger.info("Backend socket created."); + info.req["__deviceSocket"] = _socket; + callback(true); } }); server.on("connection", (webSocket) => { @@ -102,9 +100,10 @@ export class SocketProxyFactory implements ISocketProxyFactory { webSocket.on("message", (message, flags) => { let length = Buffer.byteLength(message, encoding); - let payload = new Buffer(length); - payload.write(message, 0, length, encoding); - deviceSocket.write(payload.toString()); + let payload = new Buffer(length + 4); + payload.writeInt32BE(length, 0); + payload.write(message, 4, length, encoding); + deviceSocket.write(payload); }); deviceSocket.on("end", () => { diff --git a/lib/device-sockets/ios/socket-request-executor.ts b/lib/device-sockets/ios/socket-request-executor.ts index af14dfe13c..b21e55567b 100644 --- a/lib/device-sockets/ios/socket-request-executor.ts +++ b/lib/device-sockets/ios/socket-request-executor.ts @@ -18,9 +18,12 @@ export class IOSSocketRequestExecutor implements IiOSSocketRequestExecutor { await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.getAttachAvailable(projectId), constants.IOS_OBSERVE_NOTIFICATION_COMMAND_TYPE) ]; - const observeNotificationPromises = _.map(observeNotificationSockets, s => { - return this.$iOSNotificationService.awaitNotification(deviceIdentifier, +s, timeout); - }); + const observeNotificationPromises = _(observeNotificationSockets) + .uniq() + .map(s => { + return this.$iOSNotificationService.awaitNotification(deviceIdentifier, +s, timeout); + }) + .value(); // Trigger the notifications update. await this.$iOSNotificationService.postNotification(deviceIdentifier, this.$iOSNotification.getAttachAvailabilityQuery(projectId)); diff --git a/lib/services/ios-debug-service.ts b/lib/services/ios-debug-service.ts index 3a14189884..5de0be3057 100644 --- a/lib/services/ios-debug-service.ts +++ b/lib/services/ios-debug-service.ts @@ -174,20 +174,12 @@ class IOSDebugService implements IDebugService { } private async wireDebuggerClient(projectData: IProjectData, device?: Mobile.IiOSDevice): Promise { - const factoryPromise = async () => { + const factory = async () => { let socket = device ? await device.connectToPort(inspectorBackendPort) : net.connect(inspectorBackendPort); this._sockets.push(socket); return socket; }; - const socket = await factoryPromise(); - const factory = () => { - process.nextTick(() => { - socket.emit("connect"); - }); - return socket; - }; - if (this.$options.chrome) { this._socketProxy = this.$socketProxyFactory.createWebSocketProxy(factory); From 9e30d2bcf6661f4e01acd8fbc517206252966fc0 Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Tue, 14 Mar 2017 11:56:04 +0200 Subject: [PATCH 8/8] Update ios-devic-lib version --- lib/common | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/common b/lib/common index cfd19f2eee..6bcc88c5b2 160000 --- a/lib/common +++ b/lib/common @@ -1 +1 @@ -Subproject commit cfd19f2eee38ab92c869b14d3944ecfc8f521f71 +Subproject commit 6bcc88c5b2b88438d855681fedb891b445dbafdf diff --git a/package.json b/package.json index 77af27cf8a..334c782065 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "glob": "^7.0.3", "iconv-lite": "0.4.11", "inquirer": "0.9.0", - "ios-device-lib": "0.1.0", + "ios-device-lib": "~0.3.0", "ios-mobileprovision-finder": "1.0.9", "ios-sim-portable": "~2.0.0", "lockfile": "1.0.1",