Skip to content

Commit 09ab2ff

Browse files
authored
Merge branch 'NetrisTV:master' into master
2 parents ffa5ae3 + 6018e0b commit 09ab2ff

File tree

12 files changed

+183
-97
lines changed

12 files changed

+183
-97
lines changed

package-lock.json

Lines changed: 1 addition & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app/client/HostTracker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export class HostTracker extends ManagerClient<ParamsBase, HostTrackerEvents> {
6767
// this.emit('hosts', msg.data);
6868
if (msg.data.local) {
6969
msg.data.local.forEach(({ type }) => {
70-
const secure = location.protocol === 'https';
70+
const secure = location.protocol === 'https:';
7171
const port = location.port ? parseInt(location.port, 10) : secure ? 443 : 80;
7272
const { hostname } = location;
7373
if (type !== 'android' && type !== 'ios') {

src/app/googDevice/client/DeviceTracker.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,10 +241,10 @@ export class DeviceTracker extends BaseDeviceTracker<GoogDeviceDescriptor, never
241241
}
242242
actionButton.setAttribute(Attribute.COMMAND, command);
243243
} else {
244-
const timestamp = device['last.seen.active.timestamp'];
244+
const timestamp = device['last.update.timestamp'];
245245
if (timestamp) {
246246
const date = new Date(timestamp);
247-
actionButton.title = `Last seen on ${date.toLocaleDateString()} at ${date.toLocaleTimeString()}`;
247+
actionButton.title = `Last update on ${date.toLocaleDateString()} at ${date.toLocaleTimeString()}`;
248248
} else {
249249
actionButton.title = `Not active`;
250250
}

src/server/Config.ts

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import * as process from 'process';
22
import * as fs from 'fs';
33
import * as path from 'path';
4-
import { Configuration, HostItem } from '../types/Configuration';
4+
import { Configuration, HostItem, ServerItem } from '../types/Configuration';
55
import { EnvName } from './EnvName';
66

7+
const DEFAULT_PORT = 8000;
8+
79
export class Config {
810
private static instance?: Config;
911
public static getInstance(defaultConfig?: Configuration): Config {
@@ -35,19 +37,16 @@ export class Config {
3537
if (!configPath) {
3638
return;
3739
}
38-
const isAbsolute = configPath.startsWith('/');
39-
const absolutePath = isAbsolute ? configPath : path.resolve(process.cwd(), configPath);
40+
this.fullConfig = JSON.parse(this.readFile(configPath));
41+
}
42+
43+
public readFile(pathString: string): string {
44+
const isAbsolute = pathString.startsWith('/');
45+
const absolutePath = isAbsolute ? pathString : path.resolve(process.cwd(), pathString);
4046
if (!fs.existsSync(absolutePath)) {
41-
console.error(`Can't find configuration file "${absolutePath}"`);
42-
return;
43-
}
44-
try {
45-
const configString = fs.readFileSync(absolutePath).toString();
46-
this.fullConfig = JSON.parse(configString);
47-
} catch (e) {
48-
console.error(`Failed to load configuration from file "${absolutePath}"`);
49-
console.error(`Error: ${e.message}`);
47+
throw Error(`Can't find file "${absolutePath}"`);
5048
}
49+
return fs.readFileSync(absolutePath).toString();
5150
}
5251

5352
public getHostList(): HostItem[] {
@@ -78,4 +77,16 @@ export class Config {
7877
}
7978
return this.fullConfig.runApplTracker === true;
8079
}
80+
81+
public getServers(): ServerItem[] {
82+
if (!Array.isArray(this.fullConfig.server)) {
83+
return [
84+
{
85+
secure: false,
86+
port: DEFAULT_PORT,
87+
},
88+
];
89+
}
90+
return this.fullConfig.server;
91+
}
8192
}

src/server/appl-device/services/ControlCenter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export class ControlCenter extends BaseControlCenter<ApplDeviceDescriptor> imple
4646
model,
4747
version,
4848
state,
49-
'last.seen.active.timestamp': Date.now(),
49+
'last.update.timestamp': Date.now(),
5050
};
5151
this.descriptors.set(udid, descriptor);
5252
this.emit('device', descriptor);

src/server/goog-device/Device.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export class Device extends TypedEmitter<DeviceEvents> {
5151
'ro.product.manufacturer': '',
5252
'ro.product.model': '',
5353
'ro.product.cpu.abi': '',
54-
'last.seen.active.timestamp': 0,
54+
'last.update.timestamp': 0,
5555
};
5656
this.client = AdbKit.createClient();
5757
this.setState(state);
@@ -60,7 +60,6 @@ export class Device extends TypedEmitter<DeviceEvents> {
6060
public setState(state: string): void {
6161
if (state === 'device') {
6262
this.connected = true;
63-
this.descriptor['last.seen.active.timestamp'] = Date.now();
6463
this.properties = undefined;
6564
} else {
6665
this.connected = false;
@@ -364,12 +363,12 @@ export class Device extends TypedEmitter<DeviceEvents> {
364363
return;
365364
};
366365

367-
private emitUpdate(): void {
366+
private emitUpdate(setUpdateTime = true): void {
368367
const THROTTLE = 300;
369368
const now = Date.now();
370369
const time = now - this.lastEmit;
371-
if (this.connected) {
372-
this.descriptor['last.seen.active.timestamp'] = now;
370+
if (setUpdateTime) {
371+
this.descriptor['last.update.timestamp'] = now;
373372
}
374373
if (time > THROTTLE) {
375374
this.lastEmit = now;
@@ -379,7 +378,7 @@ export class Device extends TypedEmitter<DeviceEvents> {
379378
if (!this.throttleTimeoutId) {
380379
this.throttleTimeoutId = setTimeout(() => {
381380
delete this.throttleTimeoutId;
382-
this.emitUpdate();
381+
this.emitUpdate(false);
383382
}, THROTTLE - time);
384383
}
385384
}

src/server/index.ts

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -87,35 +87,40 @@ async function loadApplModules() {
8787
loadPlatformModulesPromises.push(loadApplModules());
8888
/// #endif
8989

90-
Promise.all(loadPlatformModulesPromises).then(() => {
91-
servicesToStart.forEach((serviceClass: ServiceClass) => {
92-
const service = serviceClass.getInstance();
93-
runningServices.push(service);
94-
service.start();
90+
Promise.all(loadPlatformModulesPromises)
91+
.then(() => {
92+
servicesToStart.forEach((serviceClass: ServiceClass) => {
93+
const service = serviceClass.getInstance();
94+
runningServices.push(service);
95+
service.start();
96+
});
97+
98+
const wsService = WebSocketServer.getInstance();
99+
mwList.forEach((mwFactory: MwFactory) => {
100+
wsService.registerMw(mwFactory);
101+
});
102+
103+
mw2List.forEach((mwFactory: MwFactory) => {
104+
WebsocketMultiplexer.registerMw(mwFactory);
105+
});
106+
107+
if (process.platform === 'win32') {
108+
readline
109+
.createInterface({
110+
input: process.stdin,
111+
output: process.stdout,
112+
})
113+
.on('SIGINT', exit);
114+
}
115+
116+
process.on('SIGINT', exit);
117+
process.on('SIGTERM', exit);
118+
})
119+
.catch((error) => {
120+
console.error(error.message);
121+
exit('1');
95122
});
96123

97-
const wsService = WebSocketServer.getInstance();
98-
mwList.forEach((mwFactory: MwFactory) => {
99-
wsService.registerMw(mwFactory);
100-
});
101-
102-
mw2List.forEach((mwFactory: MwFactory) => {
103-
WebsocketMultiplexer.registerMw(mwFactory);
104-
});
105-
106-
if (process.platform === 'win32') {
107-
readline
108-
.createInterface({
109-
input: process.stdin,
110-
output: process.stdout,
111-
})
112-
.on('SIGINT', exit);
113-
}
114-
115-
process.on('SIGINT', exit);
116-
process.on('SIGTERM', exit);
117-
});
118-
119124
let interrupted = false;
120125
function exit(signal: string) {
121126
console.log(`\nReceived signal ${signal}`);

src/server/services/HttpServer.ts

Lines changed: 77 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
11
import * as http from 'http';
2+
import * as https from 'https';
23
import path from 'path';
34
import { Service } from './Service';
45
import { Utils } from '../Utils';
56
import express, { Express } from 'express';
7+
import { Config } from '../Config';
68

7-
const proto = 'http';
8-
const DEFAULT_PORT = 8000;
99
const DEFAULT_STATIC_DIR = path.join(__dirname, './public');
1010

11+
export type ServerAndPort = {
12+
server: https.Server | http.Server;
13+
port: number;
14+
};
15+
1116
export class HttpServer implements Service {
1217
private static instance: HttpServer;
13-
private static PORT = DEFAULT_PORT;
1418
private static PUBLIC_DIR = DEFAULT_STATIC_DIR;
1519
private static SERVE_STATIC = true;
16-
private server?: http.Server;
17-
private app?: Express;
20+
private servers: ServerAndPort[] = [];
21+
private mainApp?: Express;
1822

1923
protected constructor() {
2024
// nothing here
@@ -31,13 +35,6 @@ export class HttpServer implements Service {
3135
return !!this.instance;
3236
}
3337

34-
public static setPort(port: number): void {
35-
if (HttpServer.instance) {
36-
throw Error('Unable to change value after instantiation');
37-
}
38-
HttpServer.PORT = port;
39-
}
40-
4138
public static setPublicDir(dir: string): void {
4239
if (HttpServer.instance) {
4340
throw Error('Unable to change value after instantiation');
@@ -52,29 +49,85 @@ export class HttpServer implements Service {
5249
HttpServer.SERVE_STATIC = enabled;
5350
}
5451

55-
public getPort(): number {
56-
return HttpServer.PORT;
57-
}
58-
59-
public getServer(): http.Server | undefined {
60-
return this.server;
52+
public getServers(): ServerAndPort[] {
53+
return [...this.servers];
6154
}
6255

6356
public getName(): string {
64-
return `HTTP Server {tcp:${HttpServer.PORT}}`;
57+
return `HTTP(s) Server Service`;
6558
}
6659

6760
public start(): void {
68-
this.app = express();
61+
this.mainApp = express();
6962
if (HttpServer.SERVE_STATIC && HttpServer.PUBLIC_DIR) {
70-
this.app.use(express.static(HttpServer.PUBLIC_DIR));
63+
this.mainApp.use(express.static(HttpServer.PUBLIC_DIR));
7164
}
72-
this.server = http.createServer(this.app).listen(HttpServer.PORT, () => {
73-
Utils.printListeningMsg(proto, HttpServer.PORT);
65+
const config = Config.getInstance();
66+
config.getServers().forEach((serverItem) => {
67+
const { secure, port, redirectToSecure } = serverItem;
68+
let proto: string;
69+
let server: http.Server | https.Server;
70+
if (secure) {
71+
if (!serverItem.options) {
72+
throw Error('Must provide option for secure server configuration');
73+
}
74+
let { key, cert } = serverItem.options;
75+
const { keyPath, certPath } = serverItem.options;
76+
if (!key) {
77+
if (typeof keyPath !== 'string') {
78+
throw Error('Must provide parameter "key" or "keyPath"');
79+
}
80+
key = config.readFile(keyPath);
81+
}
82+
if (!cert) {
83+
if (typeof certPath !== 'string') {
84+
throw Error('Must provide parameter "cert" or "certPath"');
85+
}
86+
cert = config.readFile(certPath);
87+
}
88+
const options = { ...serverItem.options, cert, key };
89+
server = https.createServer(options, this.mainApp);
90+
proto = 'https';
91+
} else {
92+
const options = serverItem.options ? { ...serverItem.options } : {};
93+
proto = 'http';
94+
let currentApp = this.mainApp;
95+
let host = '';
96+
let port = 443;
97+
let doRedirect = false;
98+
if (redirectToSecure === true) {
99+
doRedirect = true;
100+
} else if (typeof redirectToSecure === 'object') {
101+
doRedirect = true;
102+
if (typeof redirectToSecure.port === 'number') {
103+
port = redirectToSecure.port;
104+
}
105+
if (typeof redirectToSecure.host === 'string') {
106+
host = redirectToSecure.host;
107+
}
108+
}
109+
if (doRedirect) {
110+
currentApp = express();
111+
currentApp.use(function (req, res) {
112+
const url = new URL(`https://${host ? host : req.headers.host}${req.url}`);
113+
if (port && port !== 443) {
114+
url.port = port.toString();
115+
}
116+
return res.redirect(301, url.toString());
117+
});
118+
}
119+
server = http.createServer(options, currentApp);
120+
}
121+
this.servers.push({ server, port });
122+
server.listen(port, () => {
123+
Utils.printListeningMsg(proto, port);
124+
});
74125
});
75126
}
76127

77128
public release(): void {
78-
this.server?.close();
129+
this.servers.forEach((item) => {
130+
item.server.close();
131+
});
79132
}
80133
}

0 commit comments

Comments
 (0)