imsdk-server-core
Version:
轻量级Web服务器框架、WebSocket服务器框架。采用Typescript编写,简单易用。
148 lines (147 loc) • 6.89 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PM2Adapter = void 0;
/**
* 该类将符合本库模板的服务器配置文件解析为pm2启动所需的配置信息
* pm2配置信息 http://pm2.keymetrics.io/docs/usage/application-declaration/
*/
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
class PM2Adapter {
/**
* @param processArgv 启动进程的参数,process.argv
* @param appDir pm2启动时ecosystem.config.js文件的绝对路径
* @param mchHostFile 主机名称文件绝对路径
* @param serverConfig 服务器配置的文件绝对路径 或 服务器配置的数据内容
* @param logLevel 打印解析过程的日志级别:none不打印、base打印基本信息、full打印完整信息
* @param encode 编码默认值为utf8
*/
constructor(processArgv, appDir, mchHostFile, serverConfig, logLevel = 'none', encode = 'utf8') {
const envIndex = processArgv.indexOf('--env');
if (envIndex < 0 || envIndex === processArgv.length - 1) {
throw Error('processArgv: can not found --env xxxxxxxx');
}
this._appDir = appDir;
this._appEnv = processArgv[envIndex + 1]; //--env参数后面的值是运行环境类型
this._mchHost = mchHostFile && fs_1.default.existsSync(mchHostFile) ? fs_1.default.readFileSync(mchHostFile, { encoding: encode }).trim() : null; //指定文件中读取的主机名称
let serversStr = typeof serverConfig === 'string' ? fs_1.default.readFileSync(serverConfig, { encoding: encode }) : JSON.stringify(serverConfig);
serversStr = serversStr.replace(new RegExp('\\${opt:appDir}', 'gm'), this._appDir);
serversStr = serversStr.replace(new RegExp('\\${opt:appEnv}', 'gm'), this._appEnv);
serversStr = serversStr.replace(new RegExp('\\${opt:mchHost}', 'gm'), this._mchHost);
this._servers = JSON.parse(serversStr); //指定文件中读取服务器配置信息
this._logLevel = logLevel;
this._encode = encode;
if (this._logLevel === 'base' || this._logLevel === 'full') {
console.log('---base info---');
console.log('appDir:', this._appDir);
console.log('appEnv:', this._appEnv);
console.log('mchHost:', this._mchHost);
}
}
/**
* 返回pm2启动的apps
*/
getApps() {
const clusters = this._servers[this._appEnv].clusters;
const hostBind = this._servers[this._appEnv].hostBind || false;
const defaults = this._servers[this._appEnv].defaults || {};
if (hostBind && !this._mchHost)
throw Error('Cant not read hostname.');
const apps = [];
const nodes = {};
const instEnvName = 'env_' + this._appEnv;
for (let appName in clusters) {
const cluster = clusters[appName];
nodes[appName] = [];
for (let i = 0; i < cluster.length; i++) {
const item = cluster[i];
//进程的pm2属性
const inst = {};
Object.assign(inst, defaults.PM2config || {});
Object.assign(inst, item.PM2config || {});
inst.name = (defaults.PM2config ? defaults.PM2config.name || 'app' : 'app') + '-' + (appName + '-' + (item.port || defaults.port || i));
//进程的应用参数
inst[instEnvName] = {
NODE_ENV: (this._appEnv === 'develop' || this._appEnv === 'development') ? 'development' : 'production',
MYAPP_DIR: this._appDir,
MYAPP_ENV: this._appEnv,
MYAPP_NAME: appName,
MYAPP_HOST: (item.host === undefined ? defaults.host : item.host) || null,
MYAPP_INIP: (item.inip === undefined ? defaults.inip : item.inip) || null,
MYAPP_PORT: (item.port === undefined ? defaults.port : item.port) || null,
MYAPP_SSLS: (item.ssls === undefined ? defaults.ssls : item.ssls) || null,
MYAPP_LINKS: (item.links === undefined ? defaults.links : item.links) || [],
MYAPP_NODES: nodes //全部节点集合
};
//集群的节点数据
nodes[appName].push({
host: inst[instEnvName].MYAPP_HOST,
inip: inst[instEnvName].MYAPP_INIP,
port: inst[instEnvName].MYAPP_PORT,
ssls: !!(inst[instEnvName].MYAPP_SSLS)
});
//对应主机的apps
if (!hostBind || inst[instEnvName].MYAPP_HOST === this._mchHost) {
apps.push(inst);
}
}
}
//将对象属性转换为字符串
for (let i = 0; i < apps.length; i++) {
const inst = apps[i];
inst[instEnvName].MYAPP_SSLS = JSON.stringify(inst[instEnvName].MYAPP_SSLS);
inst[instEnvName].MYAPP_LINKS = JSON.stringify(inst[instEnvName].MYAPP_LINKS);
inst[instEnvName].MYAPP_NODES = JSON.stringify(inst[instEnvName].MYAPP_NODES);
}
if (this._logLevel === 'full') {
console.log('---apps info---');
console.log('total', apps.length);
console.log(apps);
}
return apps;
}
/**
* 将pm2启动的apps写入到文件
* @param dirname 写入文件的文件夹绝对路径
* @param json 是否写入到json文件
*/
saveApps(dirname, json = false) {
if (!this.mkdirsSync(dirname)) {
throw Error('cannot create dir ' + dirname);
}
const filepath = dirname + 'ecosystem' + (json ? '.json' : '.config.js');
fs_1.default.writeFileSync(filepath, (json ? '' : 'module.exports = ') + JSON.stringify({ apps: this.getApps() }, null, 4));
if (this._logLevel === 'base' || this._logLevel === 'full') {
console.log('save to -> ', filepath, ' finished.');
}
}
/**
* 创建多级文件夹
* @param dirname 文件夹路径
*/
mkdirsSync(dirname) {
if (fs_1.default.existsSync(dirname)) {
return true;
}
else {
if (this.mkdirsSync(path_1.default.dirname(dirname))) {
try {
fs_1.default.mkdirSync(dirname);
return true;
}
catch (e) {
return false;
}
}
else {
return false;
}
}
}
get encode() { return this._encode; }
;
}
exports.PM2Adapter = PM2Adapter;