const debug = require('debug')('ee-core:ipcServer');
|
const is = require('is-type-of');
|
const { ipcMain } = require('electron');
|
const path = require('path');
|
const fs = require('fs');
|
const globby = require('globby');
|
const Utils = require('../core/lib/utils');
|
const Wrap = require('../utils/wrap');
|
const Log = require('../log');
|
|
class IpcServer {
|
constructor (app) {
|
this.app = app;
|
this.register();
|
}
|
|
register () {
|
const self = this;
|
// 遍历方法
|
const files = Utils.filePatterns();
|
const directory = path.join(this.app.config.baseDir, 'controller');
|
const filepaths = globby.sync(files, { cwd: directory });
|
|
for (const filepath of filepaths) {
|
const fullpath = path.join(directory, filepath);
|
if (!fs.statSync(fullpath).isFile()) continue;
|
|
const properties = Wrap.getProperties(filepath, {caseStyle: 'lower'});
|
const pathName = directory.split(/[/\\]/).slice(-1) + '.' + properties.join('.');
|
|
let fileObj = Utils.loadFile(fullpath);
|
const fns = {};
|
// 为了统一,仅支持class文件
|
if (is.class(fileObj) || Utils.isBytecodeClass(fileObj)) {
|
let proto = fileObj.prototype;
|
// 不遍历父类的方法
|
//while (proto !== Object.prototype) {
|
const keys = Object.getOwnPropertyNames(proto);
|
for (const key of keys) {
|
if (key === 'constructor') {
|
continue;
|
}
|
const d = Object.getOwnPropertyDescriptor(proto, key);
|
if (is.function(d.value) && !fns.hasOwnProperty(key)) {
|
fns[key] = 1;
|
}
|
}
|
//proto = Object.getPrototypeOf(proto);
|
//}
|
}
|
|
debug('register class %s fns %j', pathName, fns);
|
|
for (const key in fns) {
|
let channel = pathName + '.' + key;
|
debug('register channel %s', channel);
|
|
function findFn (app, c) {
|
try {
|
// 找函数
|
const cmd = c;
|
let fn = null;
|
if (is.string(cmd)) {
|
const actions = cmd.split('.');
|
let obj = app;
|
actions.forEach(key => {
|
obj = obj[key];
|
if (!obj) throw new Error(`class or function '${key}' not exists`);
|
});
|
fn = obj;
|
}
|
if (!fn) throw new Error('function not exists');
|
|
return fn;
|
} catch (err) {
|
Log.coreLogger.error('[ee-core] [socket/IpcServer] throw error:', err);
|
}
|
return null;
|
}
|
|
// send/on 模型
|
ipcMain.on(channel, async (event, params) => {
|
try {
|
const fn = findFn(self.app, channel);
|
const result = await fn.call(self.app, params, event);
|
|
event.returnValue = result;
|
event.reply(`${channel}`, result);
|
} catch(e) {
|
Log.coreLogger.error('[ee-core] [socket/IpcServer] send/on throw error:', e);
|
// event.returnValue = e;
|
// event.reply(`${channel}`, e);
|
}
|
});
|
|
// invoke/handle 模型
|
ipcMain.handle(channel, async (event, params) => {
|
try {
|
const fn = findFn(self.app, channel);
|
const result = await fn.call(self.app, params, event);
|
|
return result;
|
} catch(e) {
|
Log.coreLogger.error('[ee-core] [socket/IpcServer] invoke/handle throw error:', e);
|
return e
|
}
|
});
|
}
|
}
|
}
|
}
|
|
module.exports = IpcServer;
|