ee-core 2.9.2 → 2.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +65 -65
  3. package/addon/index.js +34 -34
  4. package/addon/window/index.js +98 -98
  5. package/bin/tools.js +8 -8
  6. package/config/cache.js +41 -38
  7. package/config/config.default.js +331 -330
  8. package/config/index.js +75 -73
  9. package/const/channel.js +17 -17
  10. package/const/index.js +8 -8
  11. package/controller/baseContextClass.js +34 -34
  12. package/controller/index.js +34 -34
  13. package/core/index.js +10 -10
  14. package/core/lib/ee.js +216 -216
  15. package/core/lib/loader/context_loader.js +106 -106
  16. package/core/lib/loader/ee_loader.js +435 -435
  17. package/core/lib/loader/file_loader.js +326 -326
  18. package/core/lib/loader/mixin/addon.js +32 -32
  19. package/core/lib/loader/mixin/config.js +130 -130
  20. package/core/lib/loader/mixin/controller.js +125 -125
  21. package/core/lib/loader/mixin/service.js +28 -28
  22. package/core/lib/utils/base_context_class.js +34 -34
  23. package/core/lib/utils/function.js +30 -30
  24. package/core/lib/utils/index.js +133 -133
  25. package/core/lib/utils/sequencify.js +59 -59
  26. package/core/lib/utils/timing.js +77 -77
  27. package/cross/index.js +183 -183
  28. package/cross/spawnProcess.js +183 -183
  29. package/ee/appLoader.js +48 -48
  30. package/ee/application.js +99 -99
  31. package/ee/baseApp.js +103 -102
  32. package/ee/eeApp.js +408 -408
  33. package/ee/index.js +57 -57
  34. package/electron/app/index.js +64 -58
  35. package/electron/index.js +19 -19
  36. package/electron/window/index.js +73 -73
  37. package/electron/window/winState.js +186 -186
  38. package/exception/index.js +112 -112
  39. package/html/boot.html +98 -98
  40. package/html/cross-failure.html +28 -28
  41. package/html/failure.html +28 -28
  42. package/html/index.js +13 -13
  43. package/httpclient/index.js +161 -161
  44. package/index.js +54 -54
  45. package/jobs/baseJobClass.js +16 -16
  46. package/jobs/child/app.js +65 -65
  47. package/jobs/child/forkProcess.js +145 -145
  48. package/jobs/child/index.js +82 -82
  49. package/jobs/child-pool/index.js +213 -213
  50. package/jobs/index.js +8 -8
  51. package/jobs/load-balancer/algorithm/index.js +11 -11
  52. package/jobs/load-balancer/algorithm/minimumConnection.js +18 -18
  53. package/jobs/load-balancer/algorithm/polling.js +11 -11
  54. package/jobs/load-balancer/algorithm/random.js +9 -9
  55. package/jobs/load-balancer/algorithm/specify.js +14 -14
  56. package/jobs/load-balancer/algorithm/weights.js +21 -21
  57. package/jobs/load-balancer/algorithm/weightsMinimumConnection.js +29 -29
  58. package/jobs/load-balancer/algorithm/weightsPolling.js +22 -22
  59. package/jobs/load-balancer/algorithm/weightsRandom.js +16 -16
  60. package/jobs/load-balancer/consts.js +9 -9
  61. package/jobs/load-balancer/index.js +201 -201
  62. package/jobs/load-balancer/scheduler.js +31 -31
  63. package/jobs/renderer/index.js +141 -141
  64. package/jobs/renderer/loadView.js +40 -40
  65. package/jobs/unification.js +63 -63
  66. package/loader/index.js +172 -172
  67. package/log/index.js +68 -68
  68. package/log/logger.js +86 -80
  69. package/main/index.js +56 -56
  70. package/message/childMessage.js +54 -54
  71. package/message/index.js +18 -18
  72. package/old-utils/index.js +91 -91
  73. package/package.json +38 -38
  74. package/ps/index.js +371 -371
  75. package/services/baseContextClass.js +34 -34
  76. package/services/index.js +40 -40
  77. package/socket/httpServer.js +147 -147
  78. package/socket/index.js +81 -81
  79. package/socket/io.js +27 -27
  80. package/socket/ipcServer.js +112 -112
  81. package/socket/socketServer.js +69 -67
  82. package/storage/index.js +38 -38
  83. package/storage/jsondb/adapters/Base.js +23 -23
  84. package/storage/jsondb/adapters/FileSync.js +64 -52
  85. package/storage/jsondb/main.js +55 -42
  86. package/storage/jsondbStorage.js +195 -195
  87. package/storage/sqliteStorage.js +123 -123
  88. package/utils/co.js +237 -237
  89. package/utils/copyto.js +160 -160
  90. package/utils/depd/index.js +538 -538
  91. package/utils/depd/lib/browser/index.js +77 -77
  92. package/utils/extend.js +73 -73
  93. package/utils/get-port/index.d.ts +64 -64
  94. package/utils/get-port/index.js +148 -148
  95. package/utils/helper.js +220 -220
  96. package/utils/index.js +160 -160
  97. package/utils/ip.js +261 -261
  98. package/utils/is.js +145 -145
  99. package/utils/json.js +72 -72
  100. package/utils/pargv.js +263 -263
  101. package/utils/time/index.js +19 -19
  102. package/utils/time/ms.js +162 -162
  103. package/utils/wrap.js +35 -35
package/ee/eeApp.js CHANGED
@@ -1,409 +1,409 @@
1
- const path = require('path');
2
- const fs = require('fs');
3
- const assert = require('assert');
4
- const is = require('is-type-of');
5
- const Koa = require('koa');
6
- const koaServe = require('koa-static');
7
- const https = require('https');
8
- const BaseApp = require('./baseApp');
9
- const Log = require('../log');
10
- const CoreElectron = require('../electron');
11
- const CoreElectronApp = require('../electron/app');
12
- const CoreElectronWindow = require('../electron/window');
13
- const Conf = require('../config');
14
- const Ps = require('../ps');
15
- const Socket = require('../socket');
16
- const GetPort = require('../utils/get-port');
17
- const UtilsHelper = require('../utils/helper');
18
- const HttpClient = require('../httpclient');
19
- const Cross = require('../cross');
20
- const Html = require('../html');
21
-
22
- class EeApp extends BaseApp {
23
- constructor(options = {}) {
24
- super(options);
25
-
26
- // 兼容旧的api
27
- this.electron = CoreElectron;
28
- this.mainWindow;
29
- }
30
-
31
- /**
32
- * 生成端口
33
- */
34
- async createPorts() {
35
- if (Ps.isFrameworkMode() && Conf.isWebProtocol(this.config.mainServer)) {
36
- const mainPort = await GetPort({port: parseInt(this.config.mainServer.port)});
37
- process.env.EE_MAIN_PORT = mainPort;
38
- this.config.mainServer.port = mainPort;
39
- }
40
-
41
- if (this.config.socketServer.enable) {
42
- const socketPort = await GetPort({port: parseInt(this.config.socketServer.port)});
43
- process.env.EE_SOCKET_PORT = socketPort;
44
- this.config.socketServer.port = socketPort;
45
- }
46
-
47
- if (this.config.httpServer.enable) {
48
- const httpPort = await GetPort({port: parseInt(this.config.httpServer.port)});
49
- process.env.EE_HTTP_PORT = httpPort;
50
- this.config.httpServer.port = httpPort;
51
- }
52
-
53
- // 更新db配置
54
- Conf.setAll(this.config);
55
- }
56
-
57
- /**
58
- * 启动通信模块
59
- */
60
- async startSocket() {
61
- Socket.startAll(this);
62
- }
63
-
64
- /**
65
- * 启动跨语言服务
66
- */
67
- async crossService() {
68
- Cross.create();
69
- }
70
-
71
- /**
72
- * 创建electron应用
73
- */
74
- async createElectronApp() {
75
- if (!Ps.isFrameworkMode()) return;
76
- const newApp = CoreElectronApp.create();
77
- if (!newApp) {
78
- return
79
- }
80
-
81
- await this.crossService();
82
-
83
- await this.electronAppReady();
84
- }
85
-
86
- /**
87
- * 创建应用主窗口
88
- */
89
- async createWindow() {
90
-
91
- // 初始化一个主窗口
92
- this.mainWindow = CoreElectronWindow.getMainWindow();
93
-
94
- await this.windowReady();
95
-
96
- await this._loderAddons();
97
-
98
- await this._loderPreload();
99
-
100
- this.selectAppType();
101
- }
102
-
103
- /**
104
- * 应用类型 (远程、html、单页应用)
105
- */
106
- async selectAppType() {
107
- let type = '';
108
- let url = '';
109
-
110
- // 远程模式
111
- const remoteConfig = this.config.remoteUrl;
112
- if (remoteConfig.enable == true) {
113
- type = 'remote_web';
114
- url = remoteConfig.url;
115
- this.loadMainUrl(type, url);
116
- return;
117
- }
118
-
119
- const mainServer = this.config.mainServer;
120
-
121
- // 开发环境
122
- if (Ps.isDev()) {
123
- let modeInfo;
124
- let url;
125
- let load = 'url';
126
- const configFile = './electron/config/bin.js';
127
- let electronCfg = {};
128
-
129
- const isBin = UtilsHelper.checkConfig(configFile);
130
- if (isBin) {
131
- const binConfig = UtilsHelper.loadConfig(configFile);
132
- modeInfo = binConfig.dev.frontend;
133
- electronCfg = binConfig.dev.electron;
134
- } else {
135
- // 兼容旧的 developmentMode
136
- const developmentModeConfig = this.config.developmentMode;
137
- const selectMode = developmentModeConfig.default;
138
- modeInfo = developmentModeConfig.mode[selectMode];
139
- }
140
-
141
- url = modeInfo.protocol + modeInfo.hostname + ':' + modeInfo.port;
142
- if (Conf.isFileProtocol(modeInfo)) {
143
- url = path.join(this.config.homeDir, modeInfo.directory, modeInfo.indexPath);
144
- load = 'file';
145
- }
146
-
147
- // 检查 UI serve是否启动,先加载一个boot page
148
- if (load == 'url') {
149
- // loading page
150
- let lp = Html.getFilepath('boot.html');
151
- if (electronCfg.hasOwnProperty('loadingPage') && electronCfg.loadingPage != '') {
152
- lp = path.join(this.config.homeDir, electronCfg.loadingPage);
153
- }
154
- this._loadingPage(lp);
155
-
156
- const retryTimes = modeInfo.force === true ? 3 : 60;
157
- let count = 0;
158
- let frontendReady = false;
159
- const hc = new HttpClient();
160
- while(!frontendReady && count < retryTimes){
161
- await UtilsHelper.sleep(1 * 1000);
162
- try {
163
- await hc.request(url, {
164
- method: 'GET',
165
- timeout: 1000,
166
- });
167
- frontendReady = true;
168
- } catch(err) {
169
- // console.log('The frontend service is starting');
170
- }
171
-
172
- count++;
173
- }
174
-
175
- if (frontendReady == false && modeInfo.force !== true) {
176
- const bootFailurePage = Html.getFilepath('failure.html');
177
- this.mainWindow.loadFile(bootFailurePage);
178
- Log.coreLogger.error(`[ee-core] Please check the ${url} !`);
179
- return;
180
- }
181
- }
182
-
183
- this.loadMainUrl('spa', url, load);
184
- return;
185
- }
186
-
187
- // 生产环境
188
- // cross service takeover web
189
- if (mainServer.hasOwnProperty('takeover')) {
190
- await this._crossTakeover(mainServer)
191
- return
192
- }
193
-
194
- // 主进程
195
- if (mainServer.protocol == "") {
196
- return
197
- }
198
- if (Conf.isFileProtocol(mainServer)) {
199
- url = path.join(this.config.homeDir, mainServer.indexPath);
200
- this.loadMainUrl('spa', url, 'file');
201
- } else {
202
- this.loadLocalWeb('spa');
203
- }
204
- }
205
-
206
- /**
207
- * cross service takeover web
208
- */
209
- async _crossTakeover(mainCfg = {}) {
210
- const crossConfig = this.config.cross;
211
-
212
- // loading page
213
- if (mainCfg.hasOwnProperty('loadingPage')) {
214
- const lp = path.join(this.config.homeDir, mainCfg.loadingPage);
215
- this._loadingPage(lp);
216
- }
217
-
218
- // cross service url
219
- const service = mainCfg.takeover;
220
- if (!crossConfig.hasOwnProperty(service)) {
221
- throw new Error(`[ee-core] Please Check the value of mainServer.takeover in the config file !`);
222
- }
223
- // check service
224
- if (crossConfig[service].enable != true) {
225
- throw new Error(`[ee-core] Please Check the value of cross.${service} enable is true !`);
226
- }
227
-
228
- const entityName = crossConfig[service].name;
229
- const url = Cross.getUrl(entityName);
230
-
231
- let count = 0;
232
- let serviceReady = false;
233
- const hc = new HttpClient();
234
-
235
- // 循环检查
236
- const times = Ps.isDev() ? 20 : 100;
237
- const sleeptime = Ps.isDev() ? 1000 : 100;
238
- while(!serviceReady && count < times){
239
- await UtilsHelper.sleep(sleeptime);
240
- try {
241
- await hc.request(url, {
242
- method: 'GET',
243
- timeout: 100,
244
- });
245
- serviceReady = true;
246
- } catch(err) {
247
- //console.log('The cross service is starting');
248
- }
249
- count++;
250
- }
251
- //console.log('count:', count)
252
- if (serviceReady == false) {
253
- const bootFailurePage = Html.getFilepath('cross-failure.html');
254
- this.mainWindow.loadFile(bootFailurePage);
255
- throw new Error(`[ee-core] Please check cross service [${service}] ${url} !`)
256
- }
257
-
258
- Log.coreLogger.info(`[ee-core] cross service [${service}] is started successfully`);
259
- this.loadMainUrl('spa', url);
260
- }
261
-
262
- /**
263
- * 加载本地前端资源
264
- */
265
- loadLocalWeb(mode, staticDir) {
266
- if (!staticDir) {
267
- staticDir = path.join(this.config.homeDir, 'public', 'dist')
268
- }
269
-
270
- const koaApp = new Koa();
271
- koaApp.use(koaServe(staticDir));
272
-
273
- const mainServer = this.config.mainServer;
274
- let url = mainServer.protocol + mainServer.host + ':' + mainServer.port;
275
-
276
- const isHttps = mainServer.protocol == 'https://' ? true : false;
277
- if (isHttps) {
278
- const keyFile = path.join(this.config.homeDir, mainServer.ssl.key);
279
- const certFile = path.join(this.config.homeDir, mainServer.ssl.cert);
280
- assert(fs.existsSync(keyFile), 'ssl key file is required');
281
- assert(fs.existsSync(certFile), 'ssl cert file is required');
282
-
283
- const sslOpt = {
284
- key: fs.readFileSync(keyFile),
285
- cert: fs.readFileSync(certFile)
286
- };
287
- https.createServer(sslOpt, koaApp.callback()).listen(mainServer.port, (err) => {
288
- if (err) {
289
- Log.coreLogger.info('[ee-core] [lib/eeApp] createServer error: ', err);
290
- return
291
- }
292
- this.loadMainUrl(mode, url);
293
- });
294
- } else {
295
- // 使用 host port 避免绑定到0.0.0.0
296
- const koaOpt = {
297
- host: mainServer.host,
298
- port: mainServer.port
299
- }
300
- koaApp.listen(koaOpt, () => {
301
- this.loadMainUrl(mode, url);
302
- });
303
- }
304
- }
305
-
306
- /**
307
- * 主服务
308
- * @params load <string> value: "url" 、 "file"
309
- */
310
- loadMainUrl(type, url, load = 'url') {
311
- const mainServer = this.config.mainServer;
312
- Log.coreLogger.info('[ee-core] Env: %s, Type: %s', this.config.env, type);
313
- Log.coreLogger.info('[ee-core] App running at: %s', url);
314
- if (load == 'file') {
315
- this.mainWindow.loadFile(url, mainServer.options)
316
- .then()
317
- .catch((err)=>{
318
- Log.coreLogger.error(`[ee-core] Please check the ${url} !`);
319
- });
320
- } else {
321
- this.mainWindow.loadURL(url, mainServer.options)
322
- .then()
323
- .catch((err)=>{
324
- Log.coreLogger.error(`[ee-core] Please check the ${url} !`);
325
- });
326
- }
327
- }
328
-
329
- /**
330
- * loading page
331
- */
332
- _loadingPage(name) {
333
- if (!UtilsHelper.fileIsExist(name)) {
334
- return
335
- }
336
- this.mainWindow.loadFile(name);
337
- }
338
-
339
- /**
340
- * electron app退出
341
- */
342
- async appQuit() {
343
- await this.beforeClose();
344
- CoreElectronApp.quit();
345
- }
346
-
347
- /**
348
- * 加载插件
349
- */
350
- async _loderAddons() {
351
- this.loader.loadAddons();
352
-
353
- // 注册主窗口Contents id
354
- const addonsCfg = this.config.addons;
355
- if (addonsCfg.window.enable && Ps.isFrameworkMode()) {
356
- const win = this.mainWindow;
357
- const addonWindow = this.addon.window;
358
- addonWindow.registerWCid('main', win.webContents.id);
359
- }
360
- }
361
-
362
- /**
363
- * 预加载模块
364
- */
365
- async _loderPreload() {
366
- let filepath = this.loader.resolveModule(path.join(this.config.baseDir, 'preload', 'index'));
367
- if (!filepath) return;
368
- const fileObj = this.loader.loadFile(filepath);
369
- if (is.function(fileObj) && !is.generatorFunction(fileObj) && !is.asyncFunction(fileObj)) {
370
- fileObj();
371
- } else if (is.asyncFunction(fileObj)) {
372
- await fileObj();
373
- }
374
- }
375
-
376
- /**
377
- * module模式初始化
378
- */
379
- async InitModuleMode() {
380
- if (!Ps.isModuleMode()) return;
381
-
382
- await this._loderAddons();
383
-
384
- await this._loderPreload();
385
- }
386
-
387
- /**
388
- * electron app已经准备好,主窗口还未创建
389
- */
390
- async electronAppReady() {
391
- // do some things
392
- }
393
-
394
- /**
395
- * 主应用窗口已经创建
396
- */
397
- async windowReady() {
398
- // do some things
399
- }
400
-
401
- /**
402
- * app关闭之前
403
- */
404
- async beforeClose() {
405
- // do some things
406
- }
407
- }
408
-
1
+ const path = require('path');
2
+ const fs = require('fs');
3
+ const assert = require('assert');
4
+ const is = require('is-type-of');
5
+ const Koa = require('koa');
6
+ const koaServe = require('koa-static');
7
+ const https = require('https');
8
+ const BaseApp = require('./baseApp');
9
+ const Log = require('../log');
10
+ const CoreElectron = require('../electron');
11
+ const CoreElectronApp = require('../electron/app');
12
+ const CoreElectronWindow = require('../electron/window');
13
+ const Conf = require('../config');
14
+ const Ps = require('../ps');
15
+ const Socket = require('../socket');
16
+ const GetPort = require('../utils/get-port');
17
+ const UtilsHelper = require('../utils/helper');
18
+ const HttpClient = require('../httpclient');
19
+ const Cross = require('../cross');
20
+ const Html = require('../html');
21
+
22
+ class EeApp extends BaseApp {
23
+ constructor(options = {}) {
24
+ super(options);
25
+
26
+ // 兼容旧的api
27
+ this.electron = CoreElectron;
28
+ this.mainWindow;
29
+ }
30
+
31
+ /**
32
+ * 生成端口
33
+ */
34
+ async createPorts() {
35
+ if (Ps.isFrameworkMode() && Conf.isWebProtocol(this.config.mainServer)) {
36
+ const mainPort = await GetPort({port: parseInt(this.config.mainServer.port)});
37
+ process.env.EE_MAIN_PORT = mainPort;
38
+ this.config.mainServer.port = mainPort;
39
+ }
40
+
41
+ if (this.config.socketServer.enable) {
42
+ const socketPort = await GetPort({port: parseInt(this.config.socketServer.port)});
43
+ process.env.EE_SOCKET_PORT = socketPort;
44
+ this.config.socketServer.port = socketPort;
45
+ }
46
+
47
+ if (this.config.httpServer.enable) {
48
+ const httpPort = await GetPort({port: parseInt(this.config.httpServer.port)});
49
+ process.env.EE_HTTP_PORT = httpPort;
50
+ this.config.httpServer.port = httpPort;
51
+ }
52
+
53
+ // [todo] 更新db配置 (system.json 不再主进程中使用了,后续可能在子进程中使用)
54
+ Conf.setAll(this.config);
55
+ }
56
+
57
+ /**
58
+ * 启动通信模块
59
+ */
60
+ async startSocket() {
61
+ Socket.startAll(this);
62
+ }
63
+
64
+ /**
65
+ * 启动跨语言服务
66
+ */
67
+ async crossService() {
68
+ Cross.create();
69
+ }
70
+
71
+ /**
72
+ * 创建electron应用
73
+ */
74
+ async createElectronApp() {
75
+ if (!Ps.isFrameworkMode()) return;
76
+ const newApp = CoreElectronApp.create();
77
+ if (!newApp) {
78
+ return
79
+ }
80
+
81
+ await this.crossService();
82
+
83
+ await this.electronAppReady();
84
+ }
85
+
86
+ /**
87
+ * 创建应用主窗口
88
+ */
89
+ async createWindow() {
90
+
91
+ // 初始化一个主窗口
92
+ this.mainWindow = CoreElectronWindow.getMainWindow();
93
+
94
+ await this.windowReady();
95
+
96
+ await this._loderAddons();
97
+
98
+ await this._loderPreload();
99
+
100
+ this.selectAppType();
101
+ }
102
+
103
+ /**
104
+ * 应用类型 (远程、html、单页应用)
105
+ */
106
+ async selectAppType() {
107
+ let type = '';
108
+ let url = '';
109
+
110
+ // 远程模式
111
+ const remoteConfig = this.config.remoteUrl;
112
+ if (remoteConfig.enable == true) {
113
+ type = 'remote_web';
114
+ url = remoteConfig.url;
115
+ this.loadMainUrl(type, url);
116
+ return;
117
+ }
118
+
119
+ const mainServer = this.config.mainServer;
120
+
121
+ // 开发环境
122
+ if (Ps.isDev()) {
123
+ let modeInfo;
124
+ let url;
125
+ let load = 'url';
126
+ const configFile = './electron/config/bin.js';
127
+ let electronCfg = {};
128
+
129
+ const isBin = UtilsHelper.checkConfig(configFile);
130
+ if (isBin) {
131
+ const binConfig = UtilsHelper.loadConfig(configFile);
132
+ modeInfo = binConfig.dev.frontend;
133
+ electronCfg = binConfig.dev.electron;
134
+ } else {
135
+ // 兼容旧的 developmentMode
136
+ const developmentModeConfig = this.config.developmentMode;
137
+ const selectMode = developmentModeConfig.default;
138
+ modeInfo = developmentModeConfig.mode[selectMode];
139
+ }
140
+
141
+ url = modeInfo.protocol + modeInfo.hostname + ':' + modeInfo.port;
142
+ if (Conf.isFileProtocol(modeInfo)) {
143
+ url = path.join(this.config.homeDir, modeInfo.directory, modeInfo.indexPath);
144
+ load = 'file';
145
+ }
146
+
147
+ // 检查 UI serve是否启动,先加载一个boot page
148
+ if (load == 'url') {
149
+ // loading page
150
+ let lp = Html.getFilepath('boot.html');
151
+ if (electronCfg.hasOwnProperty('loadingPage') && electronCfg.loadingPage != '') {
152
+ lp = path.join(this.config.homeDir, electronCfg.loadingPage);
153
+ }
154
+ this._loadingPage(lp);
155
+
156
+ const retryTimes = modeInfo.force === true ? 3 : 60;
157
+ let count = 0;
158
+ let frontendReady = false;
159
+ const hc = new HttpClient();
160
+ while(!frontendReady && count < retryTimes){
161
+ await UtilsHelper.sleep(1 * 1000);
162
+ try {
163
+ await hc.request(url, {
164
+ method: 'GET',
165
+ timeout: 1000,
166
+ });
167
+ frontendReady = true;
168
+ } catch(err) {
169
+ // console.log('The frontend service is starting');
170
+ }
171
+
172
+ count++;
173
+ }
174
+
175
+ if (frontendReady == false && modeInfo.force !== true) {
176
+ const bootFailurePage = Html.getFilepath('failure.html');
177
+ this.mainWindow.loadFile(bootFailurePage);
178
+ Log.coreLogger.error(`[ee-core] Please check the ${url} !`);
179
+ return;
180
+ }
181
+ }
182
+
183
+ this.loadMainUrl('spa', url, load);
184
+ return;
185
+ }
186
+
187
+ // 生产环境
188
+ // cross service takeover web
189
+ if (mainServer.hasOwnProperty('takeover')) {
190
+ await this._crossTakeover(mainServer)
191
+ return
192
+ }
193
+
194
+ // 主进程
195
+ if (mainServer.protocol == "") {
196
+ return
197
+ }
198
+ if (Conf.isFileProtocol(mainServer)) {
199
+ url = path.join(this.config.homeDir, mainServer.indexPath);
200
+ this.loadMainUrl('spa', url, 'file');
201
+ } else {
202
+ this.loadLocalWeb('spa');
203
+ }
204
+ }
205
+
206
+ /**
207
+ * cross service takeover web
208
+ */
209
+ async _crossTakeover(mainCfg = {}) {
210
+ const crossConfig = this.config.cross;
211
+
212
+ // loading page
213
+ if (mainCfg.hasOwnProperty('loadingPage')) {
214
+ const lp = path.join(this.config.homeDir, mainCfg.loadingPage);
215
+ this._loadingPage(lp);
216
+ }
217
+
218
+ // cross service url
219
+ const service = mainCfg.takeover;
220
+ if (!crossConfig.hasOwnProperty(service)) {
221
+ throw new Error(`[ee-core] Please Check the value of mainServer.takeover in the config file !`);
222
+ }
223
+ // check service
224
+ if (crossConfig[service].enable != true) {
225
+ throw new Error(`[ee-core] Please Check the value of cross.${service} enable is true !`);
226
+ }
227
+
228
+ const entityName = crossConfig[service].name;
229
+ const url = Cross.getUrl(entityName);
230
+
231
+ let count = 0;
232
+ let serviceReady = false;
233
+ const hc = new HttpClient();
234
+
235
+ // 循环检查
236
+ const times = Ps.isDev() ? 20 : 100;
237
+ const sleeptime = Ps.isDev() ? 1000 : 100;
238
+ while(!serviceReady && count < times){
239
+ await UtilsHelper.sleep(sleeptime);
240
+ try {
241
+ await hc.request(url, {
242
+ method: 'GET',
243
+ timeout: 100,
244
+ });
245
+ serviceReady = true;
246
+ } catch(err) {
247
+ //console.log('The cross service is starting');
248
+ }
249
+ count++;
250
+ }
251
+ //console.log('count:', count)
252
+ if (serviceReady == false) {
253
+ const bootFailurePage = Html.getFilepath('cross-failure.html');
254
+ this.mainWindow.loadFile(bootFailurePage);
255
+ throw new Error(`[ee-core] Please check cross service [${service}] ${url} !`)
256
+ }
257
+
258
+ Log.coreLogger.info(`[ee-core] cross service [${service}] is started successfully`);
259
+ this.loadMainUrl('spa', url);
260
+ }
261
+
262
+ /**
263
+ * 加载本地前端资源
264
+ */
265
+ loadLocalWeb(mode, staticDir) {
266
+ if (!staticDir) {
267
+ staticDir = path.join(this.config.homeDir, 'public', 'dist')
268
+ }
269
+
270
+ const koaApp = new Koa();
271
+ koaApp.use(koaServe(staticDir));
272
+
273
+ const mainServer = this.config.mainServer;
274
+ let url = mainServer.protocol + mainServer.host + ':' + mainServer.port;
275
+
276
+ const isHttps = mainServer.protocol == 'https://' ? true : false;
277
+ if (isHttps) {
278
+ const keyFile = path.join(this.config.homeDir, mainServer.ssl.key);
279
+ const certFile = path.join(this.config.homeDir, mainServer.ssl.cert);
280
+ assert(fs.existsSync(keyFile), 'ssl key file is required');
281
+ assert(fs.existsSync(certFile), 'ssl cert file is required');
282
+
283
+ const sslOpt = {
284
+ key: fs.readFileSync(keyFile),
285
+ cert: fs.readFileSync(certFile)
286
+ };
287
+ https.createServer(sslOpt, koaApp.callback()).listen(mainServer.port, (err) => {
288
+ if (err) {
289
+ Log.coreLogger.info('[ee-core] [lib/eeApp] createServer error: ', err);
290
+ return
291
+ }
292
+ this.loadMainUrl(mode, url);
293
+ });
294
+ } else {
295
+ // 使用 host port
296
+ const koaOpt = {
297
+ host: mainServer.open ? undefined : mainServer.host, // 根据配置是否开放0.0.0.0,默认关闭,避免绑定到0.0.0.0
298
+ port: mainServer.port
299
+ }
300
+ koaApp.listen(koaOpt, () => {
301
+ this.loadMainUrl(mode, url);
302
+ });
303
+ }
304
+ }
305
+
306
+ /**
307
+ * 主服务
308
+ * @params load <string> value: "url" 、 "file"
309
+ */
310
+ loadMainUrl(type, url, load = 'url') {
311
+ const mainServer = this.config.mainServer;
312
+ Log.coreLogger.info('[ee-core] Env: %s, Type: %s', this.config.env, type);
313
+ Log.coreLogger.info('[ee-core] App running at: %s', url);
314
+ if (load == 'file') {
315
+ this.mainWindow.loadFile(url, mainServer.options)
316
+ .then()
317
+ .catch((err)=>{
318
+ Log.coreLogger.error(`[ee-core] Please check the ${url} !`);
319
+ });
320
+ } else {
321
+ this.mainWindow.loadURL(url, mainServer.options)
322
+ .then()
323
+ .catch((err)=>{
324
+ Log.coreLogger.error(`[ee-core] Please check the ${url} !`);
325
+ });
326
+ }
327
+ }
328
+
329
+ /**
330
+ * loading page
331
+ */
332
+ _loadingPage(name) {
333
+ if (!UtilsHelper.fileIsExist(name)) {
334
+ return
335
+ }
336
+ this.mainWindow.loadFile(name);
337
+ }
338
+
339
+ /**
340
+ * electron app退出
341
+ */
342
+ async appQuit() {
343
+ await this.beforeClose();
344
+ CoreElectronApp.quit();
345
+ }
346
+
347
+ /**
348
+ * 加载插件
349
+ */
350
+ async _loderAddons() {
351
+ this.loader.loadAddons();
352
+
353
+ // 注册主窗口Contents id
354
+ const addonsCfg = this.config.addons;
355
+ if (addonsCfg.window.enable && Ps.isFrameworkMode()) {
356
+ const win = this.mainWindow;
357
+ const addonWindow = this.addon.window;
358
+ addonWindow.registerWCid('main', win.webContents.id);
359
+ }
360
+ }
361
+
362
+ /**
363
+ * 预加载模块
364
+ */
365
+ async _loderPreload() {
366
+ let filepath = this.loader.resolveModule(path.join(this.config.baseDir, 'preload', 'index'));
367
+ if (!filepath) return;
368
+ const fileObj = this.loader.loadFile(filepath);
369
+ if (is.function(fileObj) && !is.generatorFunction(fileObj) && !is.asyncFunction(fileObj)) {
370
+ fileObj();
371
+ } else if (is.asyncFunction(fileObj)) {
372
+ await fileObj();
373
+ }
374
+ }
375
+
376
+ /**
377
+ * module模式初始化
378
+ */
379
+ async InitModuleMode() {
380
+ if (!Ps.isModuleMode()) return;
381
+
382
+ await this._loderAddons();
383
+
384
+ await this._loderPreload();
385
+ }
386
+
387
+ /**
388
+ * electron app已经准备好,主窗口还未创建
389
+ */
390
+ async electronAppReady() {
391
+ // do some things
392
+ }
393
+
394
+ /**
395
+ * 主应用窗口已经创建
396
+ */
397
+ async windowReady() {
398
+ // do some things
399
+ }
400
+
401
+ /**
402
+ * app关闭之前
403
+ */
404
+ async beforeClose() {
405
+ // do some things
406
+ }
407
+ }
408
+
409
409
  module.exports = EeApp;