Skip to content

Commit e111b79

Browse files
committed
fix: move the ios debug and livesync sockets logic in the iOS devices
1 parent 1b52128 commit e111b79

File tree

11 files changed

+122
-183
lines changed

11 files changed

+122
-183
lines changed

.vscode/launch.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
{
88
"type": "node",
99
"request": "launch",
10-
"cwd": "/Users/tachev/Work/Test/testJsHw",
10+
"cwd": "/Users/tachev/Work/Test/debugTest",
1111
"sourceMaps": true,
1212
// In case you want to debug child processes started from CLI:
1313
// "autoAttachChildProcesses": true,
@@ -16,7 +16,8 @@
1616
// example commands
1717
"args": [
1818
"debug",
19-
"ios"
19+
"ios",
20+
"--hmr"
2021
]
2122
// "args": [ "test", "android", "--justlaunch"]
2223
// "args": [ "platform", "add", "android@1.3.0", "--path", "cliapp"]

lib/bootstrap.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ $injector.require("androidPluginBuildService", "./services/android-plugin-build-
1414
$injector.require("iOSEntitlementsService", "./services/ios-entitlements-service");
1515
$injector.require("iOSProjectService", "./services/ios-project-service");
1616
$injector.require("iOSProvisionService", "./services/ios-provision-service");
17-
$injector.require("iOSDeviceSocketService", "./services/ios-device-socket-service");
1817
$injector.require("xCConfigService", "./services/xcconfig-service");
1918

2019
$injector.require("cocoapodsService", "./services/cocoapods-service");

lib/common/definitions/mobile.d.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@ declare module Mobile {
111111
}
112112

113113
interface IiOSDevice extends IDevice {
114-
connectToPort(port: number): Promise<any>;
114+
getLiveSyncSocket(appId: string, projectDir: string): Promise<any>;
115+
getDebugSocket(appId: string, projectDir: string): Promise<any>;
115116
openDeviceLogStream(options?: IiOSLogStreamOptions): Promise<void>;
116117
}
117118

@@ -130,8 +131,6 @@ declare module Mobile {
130131
getDeviceHashService(appIdentifier: string): Mobile.IAndroidDeviceHashService;
131132
}
132133

133-
// interface IiOSSimulator extends IDevice { }
134-
135134
/**
136135
* Describes log stream options
137136
*/

lib/common/mobile/ios/device/ios-device.ts

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as applicationManagerPath from "./ios-application-manager";
22
import * as fileSystemPath from "./ios-device-file-system";
3-
import * as constants from "../../../constants";
3+
import * as commonConstants from "../../../constants";
4+
import * as constants from "../../../../constants";
45
import * as net from "net";
56
import { cache } from "../../../decorators";
67

@@ -10,39 +11,32 @@ export class IOSDevice implements Mobile.IiOSDevice {
1011
public deviceInfo: Mobile.IDeviceInfo;
1112
private socket: net.Socket;
1213

13-
// private static sockets: { [id: string]: net.Socket; } = {};
14-
15-
// get socket(): net.Socket {
16-
// return IOSDevice.sockets[this.deviceInfo.identifier];
17-
// }
18-
// set socket(newSocket: net.Socket) {
19-
// IOSDevice.sockets[this.deviceInfo.identifier] = newSocket;
20-
// }
21-
2214
private _deviceLogHandler: (...args: any[]) => void;
2315

2416
constructor(private deviceActionInfo: IOSDeviceLib.IDeviceActionInfo,
17+
private $errors: IErrors,
2518
private $injector: IInjector,
19+
private $iOSDebuggerPortService: IIOSDebuggerPortService,
20+
private $iOSSocketRequestExecutor: IiOSSocketRequestExecutor,
2621
private $processService: IProcessService,
2722
private $deviceLogProvider: Mobile.IDeviceLogProvider,
2823
private $devicePlatformsConstants: Mobile.IDevicePlatformsConstants,
2924
private $iOSDeviceProductNameMapper: Mobile.IiOSDeviceProductNameMapper,
3025
private $iosDeviceOperations: IIOSDeviceOperations,
31-
private $logger: ILogger,
3226
private $mobileHelper: Mobile.IMobileHelper) {
3327

3428
this.applicationManager = this.$injector.resolve(applicationManagerPath.IOSApplicationManager, { device: this, devicePointer: this.deviceActionInfo });
3529
this.fileSystem = this.$injector.resolve(fileSystemPath.IOSDeviceFileSystem, { device: this, devicePointer: this.deviceActionInfo });
3630

3731
const productType = deviceActionInfo.productType;
3832
const isTablet = this.$mobileHelper.isiOSTablet(productType);
39-
const deviceStatus = deviceActionInfo.status || constants.UNREACHABLE_STATUS;
33+
const deviceStatus = deviceActionInfo.status || commonConstants.UNREACHABLE_STATUS;
4034
this.deviceInfo = {
4135
identifier: deviceActionInfo.deviceId,
4236
vendor: "Apple",
4337
platform: this.$devicePlatformsConstants.iOS,
4438
status: deviceStatus,
45-
errorHelp: deviceStatus === constants.UNREACHABLE_STATUS ? `Device ${deviceActionInfo.deviceId} is ${constants.UNREACHABLE_STATUS}` : null,
39+
errorHelp: deviceStatus === commonConstants.UNREACHABLE_STATUS ? `Device ${deviceActionInfo.deviceId} is ${commonConstants.UNREACHABLE_STATUS}` : null,
4640
type: "Device",
4741
isTablet: isTablet,
4842
displayName: this.$iOSDeviceProductNameMapper.resolveProductName(deviceActionInfo.deviceName) || deviceActionInfo.deviceName,
@@ -69,31 +63,45 @@ export class IOSDevice implements Mobile.IiOSDevice {
6963

7064
@cache()
7165
public async openDeviceLogStream(): Promise<void> {
72-
if (this.deviceInfo.status !== constants.UNREACHABLE_STATUS) {
66+
if (this.deviceInfo.status !== commonConstants.UNREACHABLE_STATUS) {
7367
this._deviceLogHandler = this.actionOnDeviceLog.bind(this);
74-
this.$iosDeviceOperations.on(constants.DEVICE_LOG_EVENT_NAME, this._deviceLogHandler);
68+
this.$iosDeviceOperations.on(commonConstants.DEVICE_LOG_EVENT_NAME, this._deviceLogHandler);
7569
this.$iosDeviceOperations.startDeviceLog(this.deviceInfo.identifier);
7670
}
7771
}
7872

7973
public detach(): void {
8074
if (this._deviceLogHandler) {
81-
this.$iosDeviceOperations.removeListener(constants.DEVICE_LOG_EVENT_NAME, this._deviceLogHandler);
75+
this.$iosDeviceOperations.removeListener(commonConstants.DEVICE_LOG_EVENT_NAME, this._deviceLogHandler);
8276
}
8377
}
8478

85-
// This function works only on OSX
86-
public async connectToPort(port: number): Promise<net.Socket> {
87-
console.log("connectToPort");
79+
public async getLiveSyncSocket(appId: string, projectDir: string): Promise<net.Socket> {
80+
return this.getSocket(appId, projectDir);
81+
}
82+
83+
public async getDebugSocket(appId: string, projectDir: string): Promise<net.Socket> {
84+
return this.getSocket(appId, projectDir);
85+
}
86+
87+
private async getSocket(appId: string, projectDir: string): Promise<net.Socket> {
88+
if (this.socket) {
89+
return this.socket;
90+
}
91+
92+
await this.$iOSSocketRequestExecutor.executeAttachRequest(this, constants.AWAIT_NOTIFICATION_TIMEOUT_SECONDS, appId);
93+
const port = await this.$iOSDebuggerPortService.getPort({ projectDir, deviceId: this.deviceInfo.identifier, appId });
94+
if (!port) {
95+
this.$errors.fail("NativeScript debugger was not able to get inspector socket port.");
96+
}
97+
8898
const deviceId = this.deviceInfo.identifier;
8999
const deviceResponse = _.first((await this.$iosDeviceOperations.connectToPort([{ deviceId: deviceId, port: port }]))[deviceId]);
90100

91-
const _socket = new net.Socket();
92-
_socket.connect(deviceResponse.port, deviceResponse.host);
93-
this.socket = _socket;
94-
_socket.on("close", () => {
101+
this.socket = new net.Socket();
102+
this.socket.connect(deviceResponse.port, deviceResponse.host);
103+
this.socket.on("close", () => {
95104
this.socket = null;
96-
this.$logger.info("iOS Device socket closed!");
97105
});
98106

99107
this.$processService.attachToProcessExitSignals(this, this.destroySocket);

lib/common/mobile/ios/simulator/ios-emulator-services.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
import * as net from "net";
2-
import { connectEventuallyUntilTimeout } from "../../../helpers";
32
import { APPLE_VENDOR_NAME, DeviceTypes, RUNNING_EMULATOR_STATUS, NOT_RUNNING_EMULATOR_STATUS } from "../../../constants";
43

54
class IosEmulatorServices implements Mobile.IiOSSimulatorService {
6-
private static DEFAULT_TIMEOUT = 10000;
7-
85
constructor(private $logger: ILogger,
96
private $devicePlatformsConstants: Mobile.IDevicePlatformsConstants,
107
private $iOSSimResolver: Mobile.IiOSSimResolver,
@@ -72,7 +69,7 @@ class IosEmulatorServices implements Mobile.IiOSSimulatorService {
7269

7370
public async connectToPort(data: Mobile.IConnectToPortData): Promise<net.Socket> {
7471
try {
75-
const socket = await connectEventuallyUntilTimeout(async () => net.connect(data.port), data.timeout || IosEmulatorServices.DEFAULT_TIMEOUT);
72+
const socket = net.connect(data.port);
7673
return socket;
7774
} catch (e) {
7875
this.$logger.debug(e);

lib/common/mobile/ios/simulator/ios-simulator-device.ts

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,58 @@ import * as fileSystemPath from "./ios-simulator-file-system";
33
import * as constants from "../../../constants";
44
import * as net from "net";
55
import { cache } from "../../../decorators";
6+
import * as helpers from "../../../../common/helpers";
67

78
export class IOSSimulator implements Mobile.IiOSDevice {
9+
private static socketConnectionTimeout = 30000;
810
private _applicationManager: Mobile.IDeviceApplicationManager;
911
private _fileSystem: Mobile.IDeviceFileSystem;
1012
private socket: net.Socket;
1113

12-
// private static sockets: { [id: string]: net.Socket; } = {};
13-
14-
// get socket(): net.Socket {
15-
// return IOSSimulator.sockets[this.deviceInfo.identifier];
16-
// }
17-
// set socket(newSocket: net.Socket) {
18-
// IOSSimulator.sockets[this.deviceInfo.identifier] = newSocket;
19-
// }
20-
2114
constructor(private simulator: Mobile.IiSimDevice,
2215
private $devicePlatformsConstants: Mobile.IDevicePlatformsConstants,
16+
private $errors: IErrors,
2317
private $injector: IInjector,
18+
private $iOSDebuggerPortService: IIOSDebuggerPortService,
2419
private $iOSSimResolver: Mobile.IiOSSimResolver,
2520
private $iOSEmulatorServices: Mobile.IiOSSimulatorService,
21+
private $iOSNotification: IiOSNotification,
2622
private $iOSSimulatorLogProvider: Mobile.IiOSSimulatorLogProvider,
2723
private $logger: ILogger) { }
2824

29-
public async connectToPort(port: number): Promise<net.Socket> {
30-
console.log("connectToPort");
31-
this.socket = await this.$iOSEmulatorServices.connectToPort({ port });
32-
this.socket.on("close", () => {
33-
this.socket = null;
34-
this.$logger.info("iOS Simulator socket closed!");
35-
});
25+
public async getLiveSyncSocket(appId: string, projectDir: string): Promise<net.Socket> {
26+
return this.getSocket(appId, projectDir);
27+
}
28+
29+
public async getDebugSocket(appId: string, projectDir: string): Promise<net.Socket> {
30+
return this.getSocket(appId, projectDir);
31+
}
32+
33+
private async getSocket(appId: string, projectDir: string): Promise<net.Socket> {
34+
if (this.socket) {
35+
return this.socket;
36+
}
37+
38+
const attachRequestMessage = this.$iOSNotification.getAttachRequest(appId, this.deviceInfo.identifier);
39+
await this.$iOSEmulatorServices.postDarwinNotification(attachRequestMessage, this.deviceInfo.identifier);
40+
const port = await this.$iOSDebuggerPortService.getPort({ projectDir, deviceId: this.deviceInfo.identifier, appId });
41+
if (!port) {
42+
this.$errors.fail("NativeScript debugger was not able to get inspector socket port.");
43+
}
44+
45+
try {
46+
this.socket = await helpers.connectEventuallyUntilTimeout(
47+
async () => { return this.$iOSEmulatorServices.connectToPort({ port }) },
48+
IOSSimulator.socketConnectionTimeout);
49+
} catch (e) {
50+
this.$logger.warn(e);
51+
}
52+
53+
if (this.socket) {
54+
this.socket.on("close", () => {
55+
this.socket = null;
56+
});
57+
}
3658

3759
return this.socket;
3860
}

lib/device-sockets/ios/socket-proxy-factory.ts

Lines changed: 26 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { CONNECTION_ERROR_EVENT_NAME } from "../../constants";
33
import { PacketStream } from "./packet-stream";
44
import * as net from "net";
55
import * as ws from "ws";
6-
import * as helpers from "../../common/helpers";
76
import temp = require("temp");
87

98
export class SocketProxyFactory extends EventEmitter implements ISocketProxyFactory {
@@ -12,7 +11,6 @@ export class SocketProxyFactory extends EventEmitter implements ISocketProxyFact
1211

1312
constructor(private $logger: ILogger,
1413
private $errors: IErrors,
15-
private $iOSDeviceSocketService: Mobile.IiOSDeviceSocketsService,
1614
private $options: IOptions,
1715
private $net: INet) {
1816
super();
@@ -32,9 +30,6 @@ export class SocketProxyFactory extends EventEmitter implements ISocketProxyFact
3230
throw new Error(`TCP socket proxy is already running for device '${deviceIdentifier}'`);
3331
}
3432

35-
// await here?
36-
const socketFactory = async (callback: (_socket: net.Socket) => void) => helpers.connectEventually(factory, callback);
37-
3833
this.$logger.info("\nSetting up proxy...\nPress Ctrl + C to terminate, or disconnect.\n");
3934

4035
const server = net.createServer({
@@ -45,42 +40,40 @@ export class SocketProxyFactory extends EventEmitter implements ISocketProxyFact
4540

4641
server.on("connection", async (frontendSocket: net.Socket) => {
4742
this.$logger.info("Frontend client connected.");
48-
4943
frontendSocket.on("end", () => {
5044
this.$logger.info('Frontend socket closed!');
5145
if (!this.$options.watch) {
5246
process.exit(0);
5347
}
5448
});
5549

56-
await socketFactory((backendSocket: net.Socket) => {
57-
this.$logger.info("Backend socket created.");
50+
const backendSocket = await factory();
51+
this.$logger.info("Backend socket created.");
52+
53+
backendSocket.on("end", () => {
54+
this.$logger.info("Backend socket closed!");
55+
if (!this.$options.watch) {
56+
process.exit(0);
57+
}
58+
});
5859

59-
backendSocket.on("end", () => {
60-
this.$logger.info("Backend socket closed!");
61-
if (!this.$options.watch) {
62-
process.exit(0);
63-
}
64-
});
65-
66-
frontendSocket.on("close", () => {
67-
this.$logger.info("Frontend socket closed");
68-
if (!(<any>backendSocket).destroyed) {
69-
backendSocket.destroy();
70-
}
71-
});
72-
73-
backendSocket.on("close", () => {
74-
this.$logger.info("Backend socket closed");
75-
if (!(<any>frontendSocket).destroyed) {
76-
frontendSocket.destroy();
77-
}
78-
});
79-
80-
backendSocket.pipe(frontendSocket);
81-
frontendSocket.pipe(backendSocket);
82-
frontendSocket.resume();
60+
frontendSocket.on("close", () => {
61+
this.$logger.info("Frontend socket closed");
62+
if (!(<any>backendSocket).destroyed) {
63+
backendSocket.destroy();
64+
}
8365
});
66+
67+
backendSocket.on("close", () => {
68+
this.$logger.info("Backend socket closed");
69+
if (!(<any>frontendSocket).destroyed) {
70+
frontendSocket.destroy();
71+
}
72+
});
73+
74+
backendSocket.pipe(frontendSocket);
75+
frontendSocket.pipe(backendSocket);
76+
frontendSocket.resume();
8477
});
8578

8679
const socketFileLocation = temp.path({ suffix: ".sock" });
@@ -115,8 +108,7 @@ export class SocketProxyFactory extends EventEmitter implements ISocketProxyFact
115108
this.$logger.info("Frontend client connected.");
116109
let _socket;
117110
try {
118-
const existingServerSocket = this.$iOSDeviceSocketService.getSocket(deviceIdentifier);
119-
_socket = existingServerSocket || await helpers.connectEventuallyUntilTimeout(factory, 10000);
111+
_socket = await factory();
120112
} catch (err) {
121113
err.deviceIdentifier = deviceIdentifier;
122114
this.$logger.trace(err);
@@ -166,8 +158,6 @@ export class SocketProxyFactory extends EventEmitter implements ISocketProxyFact
166158
this.$logger.info('Frontend socket closed!');
167159
packets.destroy();
168160
deviceSocket.destroy();
169-
// delete this.deviceWebServers[deviceIdentifier];
170-
// server.close();
171161
if (!this.$options.watch) {
172162
process.exit(0);
173163
}

0 commit comments

Comments
 (0)