mm_os
Version:
MM_OS服务端架构,用于快速构建应用程序,支持网站建设、小程序后台、AI应用、物联网(IOT/AIOT)、游戏服务端等多种场景。
427 lines (401 loc) • 9.43 kB
JavaScript
require('mm_expand');
const {
Log
} = require('mm_logs');
const {
cacheAdmin
} = require('mm_cache');
const {
sqlAdmin
} = require('mm_sql');
const {
Config
} = require('mm_config');
const { TCP } = require('./tcp.js');
const { Software } = require('./software.js');
const {
Com
} = require('./com.js');
/**
* 服务器类
* 负责管理整个应用的服务端架构
*/
class Server {
static config = {
name: 'mos',
title: 'mm服务端系统',
log: {
level: 'debug',
file: false
},
mqtt: {
host: '127.0.0.1',
port: 1883,
state: 0
},
socket: {
host: '0.0.0.0',
port: 8200,
state: 0
},
sql: {
// mysql、sqlite
way: 'mysql'
},
sqlite: {
dir: './db/'.fullname(),
user: 'root',
password: '',
database: 'mm',
charset: 'utf8mb4',
connect_timeout: 5000,
connection_limit: 500
},
mysql: {
host: '127.0.0.1',
port: 3306,
user: 'root',
password: 'Asd159357',
database: '',
charset: 'utf8mb4',
timezone: '+08:00',
connect_timeout: 5000,
connection_limit: 500
},
cache: {
// 缓存方式memory、redis、mongodb
way: 'redis'
},
// 缓存基础配置
cachebase: {
dir: './cache/'.fullname(),
expire: 0,
max: 0,
persist: false, // 是否启用持久化
save_interval: 60000 // 保存间隔(毫秒)
},
// 缓存配置
redis: {
// 服务器地址
host: 'localhost',
// 端口号
port: 6379,
// 密码
password: 'asd159357',
// 数据库
database: 0,
// 前缀
prefix: 'mm_',
// 连接超时时间(ms)
connect_timeout: 5000,
// 重试次数
retry_count: 3,
// 重试间隔(ms)
retry_delay: 1000
},
// 数据库配置
mongodb: {
// 服务器地址
host: 'localhost',
// 端口号
port: 27017,
// 数据库名
database: "mm",
// 用户名
user: '',
// 密码
password: '',
// 连接选项 (MongoDB驱动7.x版本支持的参数)
min_pool_size: 10,
max_pool_size: 100,
connect_timeout_ms: 10000,
server_selection_timeout_ms: 5000,
retry_writes: true
},
web: {
state: 1,
// 访问地址
host: '127.0.0.1',
// 访问端口号
port: 8000,
// 是否启用websocket
socket: false,
// 是否启用压缩
compress: false,
// 是否启用事件
event: true,
// 是否启用事件
log: true,
// 跨域
cos: {
status: true,
origin: '*',
// "headers": "Content-Type,Content-Length,Authorization,Accept,X-Requested-With,x-auth-token,token,client_id,appid,apikey,user_id,x-forwarded-for,x-real-ip,User-Agent,cache-control,pragma,accept-encoding,connection,host"
},
// 代理转发
proxy: {},
// static 配置
static: {
// 是否开启静态文件处理
state: 1,
// 前端缓存时间,单位秒
max_age: 7200,
// 是否开启缓存
cache: true,
// 后端缓存时间,单位秒
cache_age: 0,
// 是否开启immutable缓存
immutable: true,
// 是否开启隐藏文件处理
hidden: false,
// 是否格式化文件
format: true,
// 是否指定文件扩展名
extensions: false,
// 是否开启brotli压缩
brotli: false,
// 是否开启gzip压缩
gzip: false,
// 静态文件根目录
root: './static',
// 编译vue文件,启动后会将vue转为js,可让前端通过 import xxx from './xxx.vue' 引入
compile_vue: true,
// 编译markdown文件,启动后会将markdown转为html
compile_md: true,
// 是否将files中的文件的js转换为amd格式
convert_amd: false,
// 指定路径文件需要转换
src_path: '/src',
// 需要转换的文件扩展名
files: [
'.js',
'.vue',
'.html'
],
// 是否启用文件修改监听(实时检测文件修改)
watch: true
}
}
};
#logger = $.log || console;
/**
* 构造函数
* @param {object} config 配置参数
*/
constructor(config) {
this.config = { ...Server.config };
/** == 管理层 == */
// 管理器
this.manager = {};
// 通知器
this.notifier = {};
// 消息发送器
this.sender = {};
// 广播器
this.pusher = {};
/** == 应用层 == */
// 中间件
this.middleware = {};
// 应用
this.app = {};
// 模组,用于功能/玩法扩展
this.mod = {};
// 游戏
this.game = {};
// 事件总线
this.eventer = $.eventer;
this.setConfig(config);
}
setLogger(logger) {
this.#logger = logger;
}
getLogger() {
return this.#logger;
}
log(level, msg, ...args) {
this.getLogger()[level](msg, ...args);
}
}
/**
* 设置配置
* @param {object} config 配置参数
*/
Server.prototype.setConfig = function (config) {
if (config) {
$.push(this.config, config, true);
this._preset();
}
};
/**
* 预置
*/
Server.prototype._preset = function () {
// 适配器
this.adapter = {};
/** == 基础设施 == */
// 日志
this.setLogger($.log || console);
// 数据库
this.sql = null;
// 缓存
this.cache = null;
// 文件管理
this.filer = null;
};
/**
* 初始化全局错误处理机制
*/
Server.prototype._initErrorRun = function () {
// 全局未捕获异常处理
process.on('uncaughtException', (error) => {
this.log('error', '全局未捕获异常:', error);
});
// 全局未处理Promise拒绝处理
process.on('unhandledRejection', (reason) => {
this.log('error', '全局未处理Promise拒绝:', reason);
});
};
/**
* 初始化
*/
Server.prototype.init = async function () {
await this._init();
};
/**
* 初始化
*/
Server.prototype._init = async function () {
// 初始化工具
this._initTool();
// 初始化基础设施
this._initBase();
// 初始化模块
this._initMod();
// 统一处理错误
this._initErrorRun();
};
/**
* 初始化基础设施
*/
Server.prototype._initBase = function () {
// console.time('[TIMING] _initBase');
// 获取数据库配置
var sql = { type: 'mysql', ...this.config.sql };
if (this.config.mysql) {
sql.mysql = this.config.mysql;
}
if (this.config.sqlite) {
sql.sqlite = this.config.sqlite;
}
$.sqlAdmin = sqlAdmin;
this.sql = sqlAdmin('sys', sql);
$.sql = this.sql;
// 获取缓存配置
var cache = { type: 'memory', ...this.config.cache };
if (this.config.cachebase) {
cache.cachebase = this.config.cachebase;
}
if (this.config.redis) {
cache = { ...cache, ...this.config.redis };
}
if (this.config.mongodb) {
cache.mongodb = this.config.mongodb;
}
this.cache = cacheAdmin('sys', cache);
$.cache = this.cache;
this.filer = $.file;
};
/**
* 初始化工具
*/
Server.prototype._initTool = function () {
$.log = new Log(this.config.log);
this.setLogger($.log);
$.config = new Config({
file: '/config.json'.fullname()
});
$.config.load();
$.config.setOptions(this.config);
$.config.saveAsync();
$.com = new Com();
$.com.loads();
};
/**
* 初始化模块
*/
Server.prototype._initMod = function () {
// 模板引擎
require('mm_tpl');
const Http = require('mm_https').Http;
$.Http = Http;
// 初始化软件模块
this.software = new Software(this.config, this);
this.tpc = new TCP(this.config, this);
};
/**
* 启动
*/
Server.prototype.start = async function () {
try {
if (this.status === 'created') {
await this.init();
}
await this._start();
this.log('info', '服务器启动成功');
} catch (error) {
this.log('error', '服务器启动失败:', error);
}
};
/**
* 启动
*/
Server.prototype._start = async function () {
await Promise.all([
// 连接缓存数据库
$.cache.connect(),
// 打开数据库连接
$.sql.open()
]);
// 运行模块
await this._runMod();
};
/**
* 运行模块
*/
Server.prototype._runMod = async function () {
await Promise.all([
// 启动TCP
this.tpc.run(),
// 启动软件
this.software.run()
]);
};
/**
* 停止
*/
Server.prototype.stop = async function () {
await this._stop();
};
/**
* 停止 - 私有方法
*/
Server.prototype._stop = async function () {
await Promise.all([
// 关闭数据库连接
$.sql.close(),
// 停止资源
$.cache.close()
]);
};
/**
* 运行
* @returns {object} 服务器实例
*/
Server.prototype.run = async function () {
// 初始化
await this.init();
// 启动
await this.start();
return this;
};
exports.Server = Server;