ee-core 2.7.1 → 2.8.0-beta.1

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.
@@ -262,7 +262,7 @@ module.exports = appInfo => {
262
262
 
263
263
  /* 主进程加载的地址 */
264
264
  config.mainServer = {
265
- protocol: 'http://', // http:// | https:// | file://
265
+ protocol: 'file://', // http:// | https:// | file://
266
266
  indexPath: '/public/dist/index.html',
267
267
  host: 'localhost',
268
268
  port: 7072, // 默认端口(如果端口被使用,则随机获取一个)
package/cross/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  const fs = require('fs');
2
- const crossSpawn = require('cross-spawn');
2
+ const EventEmitter = require('events');
3
3
  const path = require('path');
4
4
  const is = require('is-type-of');
5
5
  const Conf = require('../config/cache');
@@ -9,7 +9,8 @@ const UtilsPargv = require('../utils/pargv');
9
9
  const Ps = require('../ps');
10
10
  const Log = require('../log');
11
11
  const GetPort = require('../utils/get-port');
12
- const { app: electronApp } = require('electron');
12
+ const SpawnProcess = require('./spawnProcess');
13
+ const Channel = require('../const/channel');
13
14
 
14
15
  /**
15
16
  * Cross-language service
@@ -17,18 +18,24 @@ const { app: electronApp } = require('electron');
17
18
  */
18
19
  const CrossLanguageService = {
19
20
 
21
+ emitter: undefined,
22
+
23
+ /**
24
+ * pid唯一
25
+ * {pid:{name,entity}, pid:{name,entity}, ...}
26
+ */
20
27
  children: {},
21
28
 
29
+ /**
30
+ * name唯一
31
+ * {name:pid, name:pid, ...}
32
+ */
33
+ childrenMap: {},
34
+
22
35
  /**
23
36
  * create
24
37
  */
25
38
  async create() {
26
- if (!Ps.isProd()) {
27
- return
28
- }
29
-
30
- // init dir
31
- this._initPath();
32
39
 
33
40
  // boot services
34
41
  const servicesCfg = Conf.getValue('cross');
@@ -37,79 +44,113 @@ const CrossLanguageService = {
37
44
  for (let key of Object.keys(servicesCfg)) {
38
45
  let cfg = servicesCfg[key];
39
46
  if (cfg.enable == true) {
40
- this.run(cfg)
47
+ this.run(key)
41
48
  }
42
49
  }
43
50
  },
44
51
 
52
+ /**
53
+ * _initEventEmitter
54
+ */
55
+ async _initEventEmitter() {
56
+ if (this.emitter) {
57
+ return
58
+ }
59
+ this.emitter = new EventEmitter();
60
+ this.emitter.on(Channel.events.childProcessExit, (data) => {
61
+ console.log("------childProcessExit:", data)
62
+ const child = this.children[data.pid];
63
+ delete this.childrenMap[child.name];
64
+ delete this.children[data.pid];
65
+ });
66
+ this.emitter.on(Channel.events.childProcessError, (data) => {
67
+ console.log("------childProcessError:", data)
68
+ const child = this.children[data.pid];
69
+ delete this.childrenMap[child.name];
70
+ delete this.children[data.pid];
71
+ });
72
+ },
73
+
45
74
  /**
46
75
  * run
47
76
  */
48
- async run(conf = {}) {
49
- const cmdName = conf.name;
50
- const cmdPath = this._getCmdPath(cmdName);
51
- let cmdArgs = is.string(conf.args) ? [conf.args] : conf.args;
52
-
53
- // 动态生成port
54
- // if (Ps.isProd() || this.workspaces.length > 0) {
55
- let confPort = this.getArgs(cmdArgs, 'port');
56
- if (!confPort) {
57
- throw new Error(`[ee-core] [cross/run] --port parameter does not exist!`);
77
+ async run(service) {
78
+ // init dir
79
+ this._initPath();
80
+
81
+ const allConfig = Conf.all();
82
+ if (!allConfig.cross.hasOwnProperty(service)) {
83
+ throw new Error(`[ee-core] [cross] The service [${service}] config does not exit`);
84
+ }
85
+
86
+ const targetConf = Object.assign({}, allConfig.cross[service]);
87
+
88
+ // eventEmitter
89
+ this._initEventEmitter();
90
+
91
+ let cmdPath = this._getCmdPath(targetConf.name);
92
+ let cmdArgs = is.string(targetConf.args) ? [targetConf.args] : targetConf.args;
93
+ if (targetConf.hasOwnProperty('cmd')) {
94
+ cmdPath = targetConf.cmd;
95
+ }
96
+
97
+ let confPort = this._getValueFromArgs(cmdArgs, 'port');
98
+ if (UtilsHelper.validValue(confPort)) {
99
+ // 动态生成port
100
+ confPort = await GetPort({ port: confPort });
101
+ // 替换port
102
+ cmdArgs = this._replaceValue(cmdArgs, "--port=", confPort)
103
+ targetConf.args = cmdArgs;
58
104
  }
59
- confPort = await GetPort({ port: confPort });
60
- // 替换port
61
- cmdArgs = this.replaceValue(cmdArgs, "--port=", confPort)
62
105
 
63
106
  Log.coreLogger.info(`[ee-core] [cross/run] cmd: ${cmdPath}, args: ${cmdArgs}`);
64
107
 
65
- // Launch executable program
66
- let standardOutput = 'ignore';
67
- if (!Ps.isPackaged()) {
68
- standardOutput = 'inherit'
108
+ // 创建进程
109
+ const subProcess = new SpawnProcess(this, { cmdPath, cmdArgs, targetConf });
110
+ let uniqueName = targetConf.name;
111
+ if (this.childrenMap.hasOwnProperty(uniqueName)) {
112
+ uniqueName = uniqueName + "-" + String(subProcess.pid);
69
113
  }
70
- const coreProcess = crossSpawn(cmdPath, cmdArgs, { stdio: standardOutput, detached: false });
71
- coreProcess.on('close', (code, signal) => {
72
- Log.coreLogger.info(`[ee-core] [cross/run] [pid=${coreProcess.pid}, port=${confPort}] exited with code: ${code}, signal: ${signal}`);
73
- if (0 !== code) {
74
- // 弹错误窗口
75
- Log.coreLogger.error(`[ee-core] [cross/run] Please check [${cmdName}] service log !!!`);
76
- }
114
+ this.childrenMap[uniqueName] = subProcess.pid;
115
+ subProcess.name = uniqueName;
116
+ this.children[subProcess.pid] = {
117
+ name: uniqueName,
118
+ entity: subProcess
119
+ };
120
+
121
+ return subProcess;
122
+ },
77
123
 
78
- // electron quit
79
- if (conf.appExit) {
80
- setTimeout(() => {
81
- // 进程退出前的一些清理工作
82
- electronApp.quit();
83
- }, 1000)
84
- }
124
+ killAll() {
125
+ Object.keys(this.children).forEach(pid => {
126
+ console.log("-----killAll: ", pid);
127
+ this.kill(pid)
85
128
  });
86
- this.children[cmdName] = coreProcess;
87
129
  },
88
130
 
89
- kill() {
90
- Object.keys(this.children).forEach(key => {
91
- let proc = this.children[key];
92
- if (proc) {
93
- proc.kill('SIGINT');
94
- setTimeout(() => {
95
- if (proc.killed) return;
96
- proc.kill('SIGKILL');
97
- }, 500)
98
- }
99
- });
131
+ kill(pid) {
132
+ const entity = this.getProc(pid);
133
+ if (entity) {
134
+ entity.kill();
135
+ }
100
136
  },
101
137
 
102
- getArgs(argv, key) {
103
- // parse args
104
- let value = UtilsPargv(argv);
105
- if (key) {
106
- value = value[key];
138
+ killByName(name) {
139
+ const entity = this.getProcByName(name);
140
+ if (entity) {
141
+ entity.kill();
107
142
  }
143
+ },
144
+
145
+ _getValueFromArgs(argv, key) {
146
+ // parse args
147
+ const argsObj = UtilsPargv(argv);
148
+ const value = argsObj[key];
108
149
 
109
150
  return value;
110
151
  },
111
152
 
112
- replaceValue(arr, key, value) {
153
+ _replaceValue(arr, key, value) {
113
154
  arr = arr.map(item => {
114
155
  if (item.startsWith(key)) {
115
156
  let newItem = key + value;
@@ -121,11 +162,9 @@ const CrossLanguageService = {
121
162
  return arr;
122
163
  },
123
164
 
124
- getUrl(service) {
125
- const cfg = Conf.getValue('cross');
126
- const servicesCfg = cfg[service];
127
-
128
- const args = this.getArgs(servicesCfg.args);
165
+ getUrl(name) {
166
+ const entity = this.getProcByName(name);
167
+ const args = entity.getArgsObj();
129
168
  let protocol = 'http://';
130
169
  if (args.hasOwnProperty('ssl') && (args.ssl == 'true' || args.ssl == '1')) {
131
170
  protocol = 'https://';
@@ -136,6 +175,35 @@ const CrossLanguageService = {
136
175
  return url;
137
176
  },
138
177
 
178
+ // 获取 proc
179
+ getProcByName(name) {
180
+ const pid = this.childrenMap[name];
181
+ if (!pid) {
182
+ throw new Error(`[ee-core] [cross] The process named [${name}] does not exit`);
183
+ }
184
+ const entity = this.getProc(pid);
185
+
186
+ return entity;
187
+ },
188
+
189
+ // 获取 proc
190
+ getProc(pid) {
191
+ const child = this.children[pid];
192
+ if (!pid) {
193
+ throw new Error(`[ee-core] [cross] The process pid [${pid}] does not exit`);
194
+ }
195
+
196
+ return child.entity;
197
+ },
198
+
199
+ /**
200
+ * 获取pids
201
+ */
202
+ getPids() {
203
+ let pids = Object.keys(this.children);
204
+ return pids;
205
+ },
206
+
139
207
  _getCmdPath(name) {
140
208
  const coreName = UtilsIs.windows() ? name + ".exe" : name;
141
209
  const p = path.join(Ps.getExtraResourcesDir(), coreName);
@@ -146,14 +214,9 @@ const CrossLanguageService = {
146
214
  * init path
147
215
  */
148
216
  _initPath() {
149
- try {
150
- const pathname = Ps.getUserHomeConfigDir();
151
- if (!fs.existsSync(pathname)) {
152
- UtilsHelper.mkdir(pathname, {mode: 0o755});
153
- }
154
- } catch (e) {
155
- Log.coreLogger.error(e);
156
- throw new Error(`[ee-core] [cross] mkdir ${pathname} failed !`);
217
+ const pathname = Ps.getUserHomeConfigDir();
218
+ if (!fs.existsSync(pathname)) {
219
+ UtilsHelper.mkdir(pathname, {mode: 0o755});
157
220
  }
158
221
  }
159
222
  }
@@ -0,0 +1,133 @@
1
+ const EventEmitter = require('events');
2
+ const path = require('path');
3
+ const crossSpawn = require('cross-spawn');
4
+ const serialize = require('serialize-javascript');
5
+ const { app: electronApp } = require('electron');
6
+ const Log = require('../log');
7
+ const Ps = require('../ps');
8
+ const Channel = require('../const/channel');
9
+ const Helper = require('../utils/helper');
10
+ const UtilsPargv = require('../utils/pargv');
11
+
12
+ class SpawnProcess {
13
+ constructor(host, opt = {}) {
14
+ this.emitter = new EventEmitter();
15
+ this.host = host;
16
+ this.child = undefined;
17
+ this.pid = 0;
18
+ this.name = "";
19
+ this.config = {};
20
+ this._init(opt);
21
+ }
22
+
23
+
24
+ /**
25
+ * 初始化子进程
26
+ */
27
+ _init(options = {}) {
28
+ const { cmdPath, cmdArgs, targetConf } = options;
29
+ this.config = targetConf;
30
+ this.name = this.config.name;
31
+
32
+ // Launch executable program
33
+ let standardOutput = ['ignore', 'ignore', 'ignore', 'ipc'];
34
+ if (!Ps.isPackaged()) {
35
+ standardOutput = ['inherit', 'inherit', 'inherit', 'ipc'];
36
+ }
37
+ let execDir = Ps.getExtraResourcesDir();
38
+ if (this.config.hasOwnProperty('directory')) {
39
+ execDir = path.join(process.cwd(), this.config.directory);
40
+ }
41
+
42
+ const coreProcess = crossSpawn(cmdPath, cmdArgs, {
43
+ stdio: standardOutput,
44
+ detached: false,
45
+ cwd: execDir,
46
+ maxBuffer: 1024 * 1024 * 1024
47
+ });
48
+ this.child = coreProcess;
49
+ this.pid = coreProcess.pid;
50
+ coreProcess.on('close', (code, signal) => {
51
+ Log.coreLogger.info(`[ee-core] [cross/process] received a close from child-process, code:${code}, signal:${signal}, pid:${this.pid}`);
52
+
53
+ // electron quit
54
+ if (this.config.appExit) {
55
+ setTimeout(() => {
56
+ // 进程退出前的一些清理工作
57
+ electronApp.quit();
58
+ }, 1000)
59
+ }
60
+ });
61
+
62
+ coreProcess.on('message', (m) => {
63
+ Log.coreLogger.info(`[ee-core] [corss/process] received a message from child-process, message: ${serialize(m)}`);
64
+
65
+ if (!m || !m.id) {
66
+ return;
67
+ }
68
+
69
+ // 收到子进程消息,转发到 event
70
+ //this.emitter.emit(m.event, m.data);
71
+ });
72
+
73
+ coreProcess.on('exit', (code, signal) => {
74
+ let data = {
75
+ pid: this.pid
76
+ }
77
+ this.host.emitter.emit(Channel.events.childProcessExit, data);
78
+ Log.coreLogger.info(`[ee-core] [corss/process] received a exit from child-process, code:${code}, signal:${signal}, pid:${this.pid}`);
79
+ });
80
+
81
+ coreProcess.on('error', (err) => {
82
+ let data = {
83
+ pid: this.pid
84
+ }
85
+ this.host.emitter.emit(Channel.events.childProcessError, data);
86
+ Log.coreLogger.error(`[ee-core] [corss/process] received a error from child-process, error: ${err}, pid:${this.pid}`);
87
+ });
88
+ }
89
+
90
+ /**
91
+ * kill
92
+ */
93
+ kill(timeout = 1000) {
94
+ console.log("----- spawnProcess kill ---- ");
95
+ this.child.kill('SIGINT');
96
+ setTimeout(() => {
97
+ if (this.child.killed) return;
98
+ this.child.kill('SIGKILL');
99
+ }, timeout)
100
+ }
101
+
102
+ send(message) {
103
+ return this.sendByType(message, 'message');
104
+ }
105
+
106
+ close() {
107
+ return this.sendByType('close', 'close');
108
+ }
109
+
110
+ _generateId() {
111
+ const rid = Helper.getRandomString();
112
+ return `node:${this.pid}:${rid}`;
113
+ }
114
+
115
+ async sendByType(message, type) {
116
+ const msg = typeof message === 'string' ? message : JSON.stringify(message);
117
+ const id = this._generateId();
118
+
119
+ this.child.send({
120
+ id,
121
+ type,
122
+ data: msg,
123
+ });
124
+ return;
125
+ }
126
+
127
+ getArgsObj() {
128
+ const obj = UtilsPargv(this.config.args);
129
+ return obj;
130
+ }
131
+ }
132
+
133
+ module.exports = SpawnProcess;
@@ -37,7 +37,7 @@ const CoreElectronApp = {
37
37
  Electron.extra.closeWindow = true;
38
38
 
39
39
  // kill cross services
40
- Cross.kill();
40
+ Cross.killAll();
41
41
  })
42
42
 
43
43
  if (CoreApp.config.hardGpu.enable == false) {
package/main/index.js CHANGED
@@ -6,6 +6,7 @@ const Ps = require('../ps');
6
6
  const EE = require('../ee');
7
7
  const UtilsCore = require('../core/lib/utils');
8
8
  const Loader = require('../loader');
9
+ const UtilsPargv = require('../utils/pargv');
9
10
 
10
11
  class ElectronEgg {
11
12
 
@@ -23,6 +24,15 @@ class ElectronEgg {
23
24
  }
24
25
  Ps.initMode(this.mode);
25
26
 
27
+ // env 可能为空
28
+ const argsObj = UtilsPargv(process.argv);
29
+ let isDev = false;
30
+ if ( argsObj['env'] == 'development' || argsObj['env'] === 'dev' || argsObj['env'] === 'local' ) {
31
+ isDev = true;
32
+ }
33
+ console.log("argsObj env:", argsObj)
34
+ console.log("isDev:", isDev)
35
+
26
36
  // module mode
27
37
  if (Ps.isModuleMode()) {
28
38
  const { Application } = EE;
@@ -31,7 +41,7 @@ class ElectronEgg {
31
41
  }
32
42
 
33
43
  let baseDir = path.join(app.getAppPath(), 'electron');
34
- if (Utils.isEncrypt(app.getAppPath())) {
44
+ if (!isDev && Utils.isEncrypt(app.getAppPath())) {
35
45
  baseDir = Ps.getEncryptDir(app.getAppPath());
36
46
  }
37
47
 
@@ -42,7 +52,7 @@ class ElectronEgg {
42
52
  }
43
53
 
44
54
  const EEApp = UtilsCore.loadFile(indexFile);
45
- EE.app = new EEApp(this.env);
55
+ EE.app = new EEApp();
46
56
  }
47
57
  }
48
58
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ee-core",
3
- "version": "2.7.1",
3
+ "version": "2.8.0-beta.1",
4
4
  "description": "ee core",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/ps/index.js CHANGED
@@ -242,7 +242,7 @@ exports.getUserHomeDir = function() {
242
242
  }
243
243
 
244
244
  /**
245
- * 获取用户目录配置数据目录
245
+ * 获取用户配置数据目录
246
246
  */
247
247
  exports.getUserHomeConfigDir = function() {
248
248
  // const filePath = path.join(this.getHomeDir(), 'package.json');