Skip to content
This repository was archived by the owner on May 1, 2020. It is now read-only.

Commit d6de413

Browse files
committed
fix(serve): find an open port for the notification server if port is used.
1 parent b68b00b commit d6de413

File tree

2 files changed

+66
-23
lines changed

2 files changed

+66
-23
lines changed

src/serve.ts

+33-23
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { createNotificationServer } from './dev-server/notification-server';
99
import { createHttpServer } from './dev-server/http-server';
1010
import { createLiveReloadServer } from './dev-server/live-reload';
1111
import { ServeConfig, IONIC_LAB_URL } from './dev-server/serve-config';
12+
import { findClosestOpenPort } from './util/network';
1213

1314
const DEV_LOGGER_DEFAULT_PORT = 53703;
1415
const LIVE_RELOAD_DEFAULT_PORT = 35729;
@@ -17,29 +18,38 @@ const DEV_SERVER_DEFAULT_HOST = '0.0.0.0';
1718

1819
export function serve(context: BuildContext) {
1920
setContext(context);
20-
const config: ServeConfig = {
21-
httpPort: getHttpServerPort(context),
22-
host: getHttpServerHost(context),
23-
rootDir: context.rootDir,
24-
wwwDir: context.wwwDir,
25-
buildDir: context.buildDir,
26-
isCordovaServe: isCordovaServe(context),
27-
launchBrowser: launchBrowser(context),
28-
launchLab: launchLab(context),
29-
browserToLaunch: browserToLaunch(context),
30-
useLiveReload: useLiveReload(context),
31-
liveReloadPort: getLiveReloadServerPort(context),
32-
notificationPort: getNotificationPort(context),
33-
useServerLogs: useServerLogs(context),
34-
useProxy: useProxy(context),
35-
notifyOnConsoleLog: sendClientConsoleLogs(context)
36-
};
37-
38-
createNotificationServer(config);
39-
createLiveReloadServer(config);
40-
createHttpServer(config);
41-
42-
return watch(context)
21+
22+
let config: ServeConfig;
23+
const notificationPort = getNotificationPort(context);
24+
const host = getHttpServerHost(context);
25+
26+
return findClosestOpenPort(host, notificationPort)
27+
.then((notificationPortFound) => {
28+
29+
config = {
30+
httpPort: getHttpServerPort(context),
31+
host: host,
32+
rootDir: context.rootDir,
33+
wwwDir: context.wwwDir,
34+
buildDir: context.buildDir,
35+
isCordovaServe: isCordovaServe(context),
36+
launchBrowser: launchBrowser(context),
37+
launchLab: launchLab(context),
38+
browserToLaunch: browserToLaunch(context),
39+
useLiveReload: useLiveReload(context),
40+
liveReloadPort: getLiveReloadServerPort(context),
41+
notificationPort: notificationPortFound,
42+
useServerLogs: useServerLogs(context),
43+
useProxy: useProxy(context),
44+
notifyOnConsoleLog: sendClientConsoleLogs(context)
45+
};
46+
47+
createNotificationServer(config);
48+
createLiveReloadServer(config);
49+
createHttpServer(config);
50+
51+
return watch(context);
52+
})
4353
.then(() => {
4454
onReady(config, context);
4555
}, (err: BuildError) => {

src/util/network.ts

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import * as net from 'net';
2+
3+
export function findClosestOpenPort(host: string, port: number): Promise<number> {
4+
function t(portToCheck: number): Promise<number> {
5+
return isPortTaken(host, portToCheck).then(isTaken => {
6+
if (!isTaken) {
7+
return portToCheck;
8+
}
9+
return t(portToCheck + 1);
10+
});
11+
}
12+
13+
return t(port);
14+
}
15+
16+
export function isPortTaken(host: string, port: number): Promise<boolean> {
17+
return new Promise((resolve, reject) => {
18+
const tester = net.createServer()
19+
.once('error', (err: any) => {
20+
if (err.code !== 'EADDRINUSE') {
21+
return resolve(true);
22+
}
23+
resolve(true);
24+
})
25+
.once('listening', () => {
26+
tester.once('close', () => {
27+
resolve(false);
28+
})
29+
.close();
30+
})
31+
.listen(port, host);
32+
});
33+
}

0 commit comments

Comments
 (0)