microsoft/vscode-react-native

Public

mirrored from https://github.com/microsoft/vscode-react-nativeAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
0.3.0

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

src/extension/extensionServer.ts

287lines · modeblame

0502b7a8dlebu10 years ago1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for details.
3
6b6eb911dlebu10 years ago4import * as net from "net";
710f8655digeff10 years ago5import * as Q from "q";
acf08bc2dlebu10 years ago6import * as vscode from "vscode";
7
0502b7a8dlebu10 years ago8import * as em from "../common/extensionMessaging";
a289475bMeena Kunnathur Balakrishnan10 years ago9import {Log} from "../common/log/log";
f29c7bfeMeena Kunnathur Balakrishnan10 years ago10import {LogLevel} from "../common/log/logHelper";
4052c7eddaserge9 years ago11import {Packager, PackagerRunAs} from "../common/packager";
ffffa686Meena Kunnathur Balakrishnan10 years ago12import {PackagerStatus, PackagerStatusIndicator} from "./packagerStatusIndicator";
710f8655digeff10 years ago13import {LogCatMonitor} from "./android/logCatMonitor";
14import {FileSystem} from "../common/node/fileSystem";
5e651f3edigeff10 years ago15import {ConfigurationReader} from "../common/configurationReader";
df4bce40digeff10 years ago16import {SettingsHelper} from "./settingsHelper";
6e4d7a62Joshua Skelton10 years ago17import {Telemetry} from "../common/telemetry";
1c32fe84Patricio Beltran9 years ago18import {ExponentHelper} from "../common/exponent/exponentHelper";
0502b7a8dlebu10 years ago19
20export class ExtensionServer implements vscode.Disposable {
6b6eb911dlebu10 years ago21private serverInstance: net.Server = null;
3c013cdedlebu10 years ago22private messageHandlerDictionary: { [id: number]: ((...argArray: any[]) => Q.Promise<any>) } = {};
a822ac85dlebu10 years ago23private reactNativePackager: Packager;
ffffa686Meena Kunnathur Balakrishnan10 years ago24private reactNativePackageStatusIndicator: PackagerStatusIndicator;
8411fd8dDaniel Lebu10 years ago25private pipePath: string;
710f8655digeff10 years ago26private logCatMonitor: LogCatMonitor = null;
1c32fe84Patricio Beltran9 years ago27private exponentHelper: ExponentHelper;
a822ac85dlebu10 years ago28
1c32fe84Patricio Beltran9 years ago29public constructor(projectRootPath: string, reactNativePackager: Packager, packagerStatusIndicator: PackagerStatusIndicator, exponentHelper: ExponentHelper) {
445b113fdlebu10 years ago30
4f4e082ddigeff10 years ago31this.pipePath = new em.MessagingChannel(projectRootPath).getPath();
a822ac85dlebu10 years ago32this.reactNativePackager = reactNativePackager;
ffffa686Meena Kunnathur Balakrishnan10 years ago33this.reactNativePackageStatusIndicator = packagerStatusIndicator;
1c32fe84Patricio Beltran9 years ago34this.exponentHelper = exponentHelper;
a822ac85dlebu10 years ago35
36/* register handlers for all messages */
2743f19cdlebu10 years ago37this.messageHandlerDictionary[em.ExtensionMessage.START_PACKAGER] = this.startPackager;
38this.messageHandlerDictionary[em.ExtensionMessage.STOP_PACKAGER] = this.stopPackager;
f2a58eefBret Johnson9 years ago39this.messageHandlerDictionary[em.ExtensionMessage.RESTART_PACKAGER] = this.restartPackager;
2743f19cdlebu10 years ago40this.messageHandlerDictionary[em.ExtensionMessage.PREWARM_BUNDLE_CACHE] = this.prewarmBundleCache;
710f8655digeff10 years ago41this.messageHandlerDictionary[em.ExtensionMessage.START_MONITORING_LOGCAT] = this.startMonitoringLogCat;
c2bf3c4fdigeff10 years ago42this.messageHandlerDictionary[em.ExtensionMessage.STOP_MONITORING_LOGCAT] = this.stopMonitoringLogCat;
5e651f3edigeff10 years ago43this.messageHandlerDictionary[em.ExtensionMessage.GET_PACKAGER_PORT] = this.getPackagerPort;
6e4d7a62Joshua Skelton10 years ago44this.messageHandlerDictionary[em.ExtensionMessage.SEND_TELEMETRY] = this.sendTelemetry;
514df4f4Patricio Beltran10 years ago45this.messageHandlerDictionary[em.ExtensionMessage.OPEN_FILE_AT_LOCATION] = this.openFileAtLocation;
1c32fe84Patricio Beltran9 years ago46this.messageHandlerDictionary[em.ExtensionMessage.START_EXPONENT_PACKAGER] = this.startExponentPackager;
280c0746Patricio Beltran9 years ago47this.messageHandlerDictionary[em.ExtensionMessage.SHOW_INFORMATION_MESSAGE] = this.showInformationMessage;
a822ac85dlebu10 years ago48}
0502b7a8dlebu10 years ago49
50/**
51* Starts the server.
52*/
53public setup(): Q.Promise<void> {
54
55let deferred = Q.defer<void>();
56
57let launchCallback = (error: any) => {
4f4e082ddigeff10 years ago58Log.logInternalMessage(LogLevel.Info, `Extension messaging server started at ${this.pipePath}.`);
0502b7a8dlebu10 years ago59if (error) {
60deferred.reject(error);
61} else {
62deferred.resolve(null);
63}
64};
65
6b6eb911dlebu10 years ago66this.serverInstance = net.createServer(this.handleSocket.bind(this));
67this.serverInstance.on("error", this.recoverServer.bind(this));
8411fd8dDaniel Lebu10 years ago68this.serverInstance.listen(this.pipePath, launchCallback);
0502b7a8dlebu10 years ago69
70return deferred.promise;
71}
72
73/**
74* Stops the server.
75*/
76public dispose(): void {
77if (this.serverInstance) {
78this.serverInstance.close();
acf08bc2dlebu10 years ago79this.serverInstance = null;
0502b7a8dlebu10 years ago80}
710f8655digeff10 years ago81
c2bf3c4fdigeff10 years ago82this.stopMonitoringLogCat();
0502b7a8dlebu10 years ago83}
84
5e651f3edigeff10 years ago85/**
86* Message handler for GET_PACKAGER_PORT.
87*/
88private getPackagerPort(): Q.Promise<number> {
df4bce40digeff10 years ago89return Q(SettingsHelper.getPackagerPort());
5e651f3edigeff10 years ago90}
91
a822ac85dlebu10 years ago92/**
93* Message handler for START_PACKAGER.
94*/
5e651f3edigeff10 years ago95private startPackager(port?: any): Q.Promise<any> {
b0af599cJimmy Thomson9 years ago96return this.reactNativePackager.isRunning().then((running) => {
97if (running) {
4052c7eddaserge9 years ago98if (this.reactNativePackager.getRunningAs() !== PackagerRunAs.REACT_NATIVE) {
99return this.reactNativePackager.stop().then(() =>
100this.reactNativePackageStatusIndicator.updatePackagerStatus(PackagerStatus.PACKAGER_STOPPED)
101);
102}
103
104Log.logMessage("Attaching to running React Native packager");
b0af599cJimmy Thomson9 years ago105}
106}).then(() =>
107this.exponentHelper.configureReactNativeEnvironment()
108).then(() => {
109const portToUse = ConfigurationReader.readIntWithDefaultSync(port, SettingsHelper.getPackagerPort());
110return this.reactNativePackager.startAsReactNative(portToUse);
111})
112.then(() =>
5e651f3edigeff10 years ago113this.reactNativePackageStatusIndicator.updatePackagerStatus(PackagerStatus.PACKAGER_STARTED));
a822ac85dlebu10 years ago114}
115
1c32fe84Patricio Beltran9 years ago116/**
117* Message handler for START_EXPONENT_PACKAGER.
118*/
119private startExponentPackager(port?: any): Q.Promise<any> {
b0af599cJimmy Thomson9 years ago120return this.reactNativePackager.isRunning().then((running) => {
121if (running) {
4052c7eddaserge9 years ago122if (this.reactNativePackager.getRunningAs() !== PackagerRunAs.EXPONENT) {
123return this.reactNativePackager.stop().then(() =>
124this.reactNativePackageStatusIndicator.updatePackagerStatus(PackagerStatus.PACKAGER_STOPPED));
125}
126
127Log.logMessage("Attaching to running Exponent packager");
b0af599cJimmy Thomson9 years ago128}
129}).then(() =>
130this.exponentHelper.configureExponentEnvironment()
131).then(() =>
132this.exponentHelper.loginToExponent(
133(message, password) => { return Q(vscode.window.showInputBox({ placeHolder: message, password: password })); },
134(message) => { return Q(vscode.window.showInformationMessage(message)); }
135))
136.then(() => {
137const portToUse = ConfigurationReader.readIntWithDefaultSync(port, SettingsHelper.getPackagerPort());
138return this.reactNativePackager.startAsExponent(portToUse);
139})
140.then(exponentUrl => {
141this.reactNativePackageStatusIndicator.updatePackagerStatus(PackagerStatus.EXPONENT_PACKAGER_STARTED);
142return exponentUrl;
143});
1c32fe84Patricio Beltran9 years ago144}
145
a822ac85dlebu10 years ago146/**
147* Message handler for STOP_PACKAGER.
148*/
149private stopPackager(): Q.Promise<any> {
ffffa686Meena Kunnathur Balakrishnan10 years ago150return this.reactNativePackager.stop()
151.then(() => this.reactNativePackageStatusIndicator.updatePackagerStatus(PackagerStatus.PACKAGER_STOPPED));
a822ac85dlebu10 years ago152}
153
f2a58eefBret Johnson9 years ago154/**
155* Message handler for RESTART_PACKAGER.
156*/
157private restartPackager(port?: any): Q.Promise<any> {
158const portToUse = ConfigurationReader.readIntWithDefaultSync(port, SettingsHelper.getPackagerPort());
159return this.reactNativePackager.restart(portToUse)
160.then(() =>
161this.reactNativePackageStatusIndicator.updatePackagerStatus(PackagerStatus.PACKAGER_STARTED));
162}
163
2743f19cdlebu10 years ago164/**
165* Message handler for PREWARM_BUNDLE_CACHE.
166*/
3c013cdedlebu10 years ago167private prewarmBundleCache(platform: string): Q.Promise<any> {
2743f19cdlebu10 years ago168return this.reactNativePackager.prewarmBundleCache(platform);
169}
170
710f8655digeff10 years ago171/**
172* Message handler for START_MONITORING_LOGCAT.
173*/
c2bf3c4fdigeff10 years ago174private startMonitoringLogCat(deviceId: string, logCatArguments: string): Q.Promise<any> {
175this.stopMonitoringLogCat(); // Stop previous logcat monitor if it's running
710f8655digeff10 years ago176
c2bf3c4fdigeff10 years ago177// this.logCatMonitor can be mutated, so we store it locally too
178const logCatMonitor = this.logCatMonitor = new LogCatMonitor(deviceId, logCatArguments);
179logCatMonitor.start() // The LogCat will continue running forever, so we don't wait for it
710f8655digeff10 years ago180.catch(error =>
c2bf3c4fdigeff10 years ago181Log.logWarning("Error while monitoring LogCat", error))
710f8655digeff10 years ago182.done();
183
184return Q.resolve<void>(void 0);
185}
186
514df4f4Patricio Beltran10 years ago187/**
188* Message handler for OPEN_FILE_AT_LOCATION
189*/
190private openFileAtLocation(filename: string, lineNumber: number): Q.Promise<void> {
81f88231Patricio Beltran9 years ago191return Q(vscode.workspace.openTextDocument(vscode.Uri.file(filename)).then((document: vscode.TextDocument) => {
192return vscode.window.showTextDocument(document).then((editor: vscode.TextEditor) => {
514df4f4Patricio Beltran10 years ago193let range = editor.document.lineAt(lineNumber - 1).range;
194editor.selection = new vscode.Selection(range.start, range.end);
195editor.revealRange(range, vscode.TextEditorRevealType.InCenter);
196});
197}));
198}
199
c2bf3c4fdigeff10 years ago200private stopMonitoringLogCat(): Q.Promise<void> {
710f8655digeff10 years ago201if (this.logCatMonitor) {
202this.logCatMonitor.dispose();
203this.logCatMonitor = null;
204}
c2bf3c4fdigeff10 years ago205
206return Q.resolve<void>(void 0);
710f8655digeff10 years ago207}
208
6e4d7a62Joshua Skelton10 years ago209/**
210* Sends telemetry
211*/
212private sendTelemetry(extensionId: string, extensionVersion: string, appInsightsKey: string, eventName: string, properties: {[key: string]: string}, measures: {[key: string]: number}): Q.Promise<any> {
213Telemetry.sendExtensionTelemetry(extensionId, extensionVersion, appInsightsKey, eventName, properties, measures);
214return Q.resolve({});
215}
216
0502b7a8dlebu10 years ago217/**
6b6eb911dlebu10 years ago218* Extension message handler.
0502b7a8dlebu10 years ago219*/
6b6eb911dlebu10 years ago220private handleExtensionMessage(messageWithArgs: em.MessageWithArguments): Q.Promise<any> {
221let handler = this.messageHandlerDictionary[messageWithArgs.message];
222if (handler) {
f29c7bfeMeena Kunnathur Balakrishnan10 years ago223Log.logInternalMessage(LogLevel.Info, "Handling message: " + em.ExtensionMessage[messageWithArgs.message]);
6b6eb911dlebu10 years ago224return handler.apply(this, messageWithArgs.args);
225} else {
226return Q.reject("Invalid message: " + messageWithArgs.message);
227}
228}
0502b7a8dlebu10 years ago229
6b6eb911dlebu10 years ago230/**
231* Handles connections to the server.
232*/
233private handleSocket(socket: net.Socket): void {
d40a8b0fdlebu10 years ago234let handleError = (e: any) => {
5e651f3edigeff10 years ago235Log.logError(e);
d40a8b0fdlebu10 years ago236socket.end(em.ErrorMarker);
237};
238
6b6eb911dlebu10 years ago239let dataCallback = (data: any) => {
35c2ec28dlebu10 years ago240try {
6b6eb911dlebu10 years ago241let messageWithArgs: em.MessageWithArguments = JSON.parse(data);
242this.handleExtensionMessage(messageWithArgs)
35c2ec28dlebu10 years ago243.then(result => {
6b6eb911dlebu10 years ago244socket.end(JSON.stringify(result));
35c2ec28dlebu10 years ago245})
d40a8b0fdlebu10 years ago246.catch((e) => { handleError(e); })
35c2ec28dlebu10 years ago247.done();
248} catch (e) {
d40a8b0fdlebu10 years ago249handleError(e);
2743f19cdlebu10 years ago250}
6b6eb911dlebu10 years ago251};
252
253socket.on("data", dataCallback);
254};
0502b7a8dlebu10 years ago255
256/**
6b6eb911dlebu10 years ago257* Recovers the server in case the named socket we use already exists, but no other instance of VSCode is active.
0502b7a8dlebu10 years ago258*/
6b6eb911dlebu10 years ago259private recoverServer(error: any): void {
260let errorHandler = (e: any) => {
261/* The named socket is not used. */
262if (e.code === "ECONNREFUSED") {
8411fd8dDaniel Lebu10 years ago263new FileSystem().removePathRecursivelyAsync(this.pipePath)
6b6eb911dlebu10 years ago264.then(() => {
8411fd8dDaniel Lebu10 years ago265this.serverInstance.listen(this.pipePath);
6b6eb911dlebu10 years ago266})
267.done();
268}
269};
270
271/* The named socket already exists. */
272if (error.code === "EADDRINUSE") {
273let clientSocket = new net.Socket();
274clientSocket.on("error", errorHandler);
8411fd8dDaniel Lebu10 years ago275clientSocket.connect(this.pipePath, function() {
6b6eb911dlebu10 years ago276clientSocket.end();
277});
0502b7a8dlebu10 years ago278}
279}
280c0746Patricio Beltran9 years ago280
281/**
282* Message handler for SHOW_INFORMATION_MESSAGE
283*/
284private showInformationMessage(message: string): Q.Promise<void> {
285return Q(vscode.window.showInformationMessage(message)).then(() => {});
286}
0502b7a8dlebu10 years ago287}