Skip to content

Commit a2c4e4f

Browse files
Merge pull request #1702 from NativeScript/vladimirov/fix-socket-destroy
Fix livesync for ios devices
2 parents f4ea96b + 2a7049d commit a2c4e4f

File tree

2 files changed

+59
-13
lines changed

2 files changed

+59
-13
lines changed

lib/providers/livesync-provider.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,22 @@ export class LiveSyncProvider implements ILiveSyncProvider {
1212

1313
private static FAST_SYNC_FILE_EXTENSIONS = [".css", ".xml"];
1414

15+
private platformSpecificLiveSyncServicesCache: IDictionary<any> = {};
1516
public get platformSpecificLiveSyncServices(): IDictionary<any> {
1617
return {
1718
android: (_device: Mobile.IDevice, $injector: IInjector): IPlatformLiveSyncService => {
18-
return $injector.resolve(this.$androidLiveSyncServiceLocator.factory, {_device: _device});
19+
if(!this.platformSpecificLiveSyncServicesCache[_device.deviceInfo.identifier]) {
20+
this.platformSpecificLiveSyncServicesCache[_device.deviceInfo.identifier] = $injector.resolve(this.$androidLiveSyncServiceLocator.factory, {_device: _device});
21+
}
22+
23+
return this.platformSpecificLiveSyncServicesCache[_device.deviceInfo.identifier];
1924
},
2025
ios: (_device: Mobile.IDevice, $injector: IInjector) => {
21-
return $injector.resolve(this.$iosLiveSyncServiceLocator.factory, {_device: _device});
26+
if(!this.platformSpecificLiveSyncServicesCache[_device.deviceInfo.identifier]) {
27+
this.platformSpecificLiveSyncServicesCache[_device.deviceInfo.identifier] = $injector.resolve(this.$iosLiveSyncServiceLocator.factory, {_device: _device});
28+
}
29+
30+
return this.platformSpecificLiveSyncServicesCache[_device.deviceInfo.identifier];
2231
}
2332
};
2433
}

lib/services/livesync/ios-livesync-service.ts

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@ let currentPageReloadId = 0;
99

1010
class IOSLiveSyncService extends liveSyncServiceBaseLib.LiveSyncServiceBase<Mobile.IiOSDevice> implements IPlatformLiveSyncService {
1111
private static BACKEND_PORT = 18181;
12+
private socket: net.Socket;
1213

1314
constructor(_device: Mobile.IDevice,
1415
private $iOSSocketRequestExecutor: IiOSSocketRequestExecutor,
1516
private $iOSNotification: IiOSNotification,
1617
private $iOSEmulatorServices: Mobile.IiOSSimulatorService,
1718
private $injector: IInjector,
18-
private $logger: ILogger) {
19+
private $logger: ILogger,
20+
private $options: IOptions) {
1921
super(_device);
2022
}
2123

@@ -34,36 +36,71 @@ class IOSLiveSyncService extends liveSyncServiceBaseLib.LiveSyncServiceBase<Mobi
3436
return (() => {
3537
let timeout = 9000;
3638
if (this.device.isEmulator) {
37-
helpers.connectEventually(() => net.connect(IOSLiveSyncService.BACKEND_PORT), (socket: net.Socket) => this.sendPageReloadMessage(socket));
39+
if (!this.socket) {
40+
helpers.connectEventually(() => net.connect(IOSLiveSyncService.BACKEND_PORT), (socket: net.Socket) => {
41+
this.socket = socket;
42+
if(this.$options.watch) {
43+
this.attachProcessExitHandlers();
44+
}
45+
this.sendPageReloadMessage();
46+
});
47+
} else {
48+
this.sendPageReloadMessage();
49+
}
3850
this.$iOSEmulatorServices.postDarwinNotification(this.$iOSNotification.attachRequest).wait();
3951
} else {
4052
this.$iOSSocketRequestExecutor.executeAttachRequest(this.device, timeout).wait();
41-
let socket = this.device.connectToPort(IOSLiveSyncService.BACKEND_PORT);
42-
this.sendPageReloadMessage(socket);
53+
this.socket = this.device.connectToPort(IOSLiveSyncService.BACKEND_PORT);
54+
this.sendPageReloadMessage();
4355
}
4456
}).future<void>()();
4557
}
4658

47-
private sendPageReloadMessage(socket: net.Socket): void {
59+
private sendPageReloadMessage(): void {
4860
try {
49-
this.sendPageReloadMessageCore(socket);
50-
socket.once("data", (data: NodeBuffer|string) => {
61+
this.sendPageReloadMessageCore();
62+
this.socket.on("data", (data: NodeBuffer|string) => {
5163
this.$logger.trace(`Socket sent data: ${data.toString()}`);
52-
socket.destroy();
64+
this.destroySocketIfNecessary();
5365
});
5466
} catch(err) {
5567
this.$logger.trace("Error while sending page reload:", err);
56-
socket.destroy();
68+
this.destroySocketIfNecessary();
5769
}
5870
}
5971

60-
private sendPageReloadMessageCore(socket: net.Socket): void {
72+
private sendPageReloadMessageCore(): void {
6173
let message = `{ "method":"Page.reload","params":{"ignoreCache":false},"id":${++currentPageReloadId} }`;
6274
let length = Buffer.byteLength(message, "utf16le");
6375
let payload = new Buffer(length + 4);
6476
payload.writeInt32BE(length, 0);
6577
payload.write(message, 4, length, "utf16le");
66-
socket.write(payload);
78+
this.socket.write(payload);
79+
}
80+
81+
private attachProcessExitHandlers(): void {
82+
process.on("exit", (exitCode: number) => {
83+
this.destroySocket();
84+
});
85+
86+
process.on("SIGTERM", () => {
87+
this.destroySocket();
88+
});
89+
90+
process.on("SIGINT", () => {
91+
this.destroySocket();
92+
});
93+
}
94+
95+
private destroySocketIfNecessary(): void {
96+
if(!this.$options.watch) {
97+
this.destroySocket();
98+
}
99+
}
100+
101+
private destroySocket(): void {
102+
this.socket.destroy();
103+
this.socket = null;
67104
}
68105
}
69106
$injector.register("iosLiveSyncServiceLocator", {factory: IOSLiveSyncService});

0 commit comments

Comments
 (0)