mm_os 4.0.8 → 4.1.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.
package/server.js CHANGED
@@ -11,47 +11,10 @@ const {
11
11
  const {
12
12
  Config
13
13
  } = require('mm_config');
14
- const {
15
- Manager,
16
- Drive
17
- } = require('mm_machine');
18
14
 
19
- const {
20
- App
21
- } = require('./core/app/index.js');
22
- const {
23
- Game
24
- } = require('./core/game/index.js');
25
- // const {
26
- // Zone
27
- // } = require('./core/zone/index.js');
28
- const {
29
- Mod
30
- } = require('./core/mod/index.js');
31
- const {
32
- Middleware
33
- } = require('./core/middleware/index.js');
34
- const {
35
- Notifier
36
- } = require('./core/notifier/index.js');
37
- const {
38
- Pusher
39
- } = require('./core/pusher/index.js');
40
- const {
41
- Sender
42
- } = require('./core/sender/index.js');
43
- const {
44
- Web
45
- } = require('./adapter/web.js');
46
- const {
47
- Mqtt
48
- } = require('./adapter/mqtt.js');
49
- const {
50
- Socket
51
- } = require('./adapter/socket.js');
52
- const {
53
- WebSocket
54
- } = require('./adapter/websocket.js');
15
+ const { TCP } = require('./tpc');
16
+ const { Software } = require('./software');
17
+
55
18
  const {
56
19
  Com
57
20
  } = require('./com.js');
@@ -60,7 +23,7 @@ const {
60
23
  * 服务器类
61
24
  * 负责管理整个应用的服务端架构
62
25
  */
63
- class Server extends Drive {
26
+ class Server {
64
27
  static config = {
65
28
  name: 'mos',
66
29
  title: 'mm服务端系统',
@@ -88,7 +51,7 @@ class Server extends Drive {
88
51
  password: '',
89
52
  database: 'mm',
90
53
  charset: 'utf8mb4',
91
- connect_timeout: 20000,
54
+ connect_timeout: 5000,
92
55
  connection_limit: 500
93
56
  },
94
57
  mysql: {
@@ -99,7 +62,7 @@ class Server extends Drive {
99
62
  database: '',
100
63
  charset: 'utf8mb4',
101
64
  timezone: '+08:00',
102
- connect_timeout: 20000,
65
+ connect_timeout: 5000,
103
66
  connection_limit: 500
104
67
  },
105
68
  cache: {
@@ -127,7 +90,7 @@ class Server extends Drive {
127
90
  // 前缀
128
91
  prefix: "mm_",
129
92
  // 连接超时时间(ms)
130
- connect_timeout: 10000,
93
+ connect_timeout: 5000,
131
94
  // 重试次数
132
95
  retry_count: 3,
133
96
  // 重试间隔(ms)
@@ -217,13 +180,14 @@ class Server extends Drive {
217
180
  }
218
181
  }
219
182
  };
183
+ #logger = $.log || console;
220
184
 
221
185
  /**
222
186
  * 构造函数
223
187
  * @param {object} config 配置参数
224
188
  */
225
189
  constructor(config) {
226
- super({ ...Server.config, ...config });
190
+ this.config = { ...Server.config };
227
191
  /** == 管理层 == */
228
192
  // 管理器
229
193
  this.manager = {};
@@ -245,9 +209,30 @@ class Server extends Drive {
245
209
  this.game = {};
246
210
  // 事件总线
247
211
  this.eventer = $.eventer;
212
+ this.setConfig(config);
213
+ }
214
+ setLogger(logger) {
215
+ this.#logger = logger;
216
+ }
217
+ getLogger() {
218
+ return this.#logger;
219
+ }
220
+ log(level, msg, ...args) {
221
+ this.getLogger()[level](msg, ...args);
248
222
  }
249
223
  }
250
224
 
225
+ /**
226
+ * 设置配置
227
+ * @param {object} config 配置参数
228
+ */
229
+ Server.prototype.setConfig = function (config) {
230
+ if (config) {
231
+ $.push(this.config, config, true);
232
+ this._preset();
233
+ }
234
+ };
235
+
251
236
  /**
252
237
  * 预置
253
238
  */
@@ -266,49 +251,52 @@ Server.prototype._preset = function () {
266
251
  this.filer = null;
267
252
  };
268
253
 
254
+
269
255
  /**
270
- * 深度合并对象
271
- * @param {object} target 目标对象
272
- * @param {object} source 源对象
273
- * @returns {object} 合并后的对象
256
+ * 初始化全局错误处理机制
274
257
  */
275
- Server.prototype.deepMerge = function (target, source) {
276
- for (let key of Object.keys(source)) {
277
- if (source[key] instanceof Object && key in target) {
278
- Object.assign(source[key], this.deepMerge(target[key], source[key]));
279
- }
280
- }
281
- return {
282
- ...target,
283
- ...source
284
- };
258
+ Server.prototype._initErrorRun = function () {
259
+ // 全局未捕获异常处理
260
+ process.on('uncaughtException', (error) => {
261
+ this.log('error', '全局未捕获异常:', error);
262
+ });
263
+
264
+ // 全局未处理Promise拒绝处理
265
+ process.on('unhandledRejection', (reason) => {
266
+ this.log('error', '全局未处理Promise拒绝:', reason);
267
+ });
285
268
  };
286
269
 
287
270
  /**
288
- * 设置配置
289
- * @param {object} config 配置参数
271
+ * 初始化
290
272
  */
291
- Server.prototype.setConfig = function (config) {
292
- if (config) {
293
- this.config = this.deepMerge(this.config, config);
294
- this._preset();
295
- }
273
+ Server.prototype.init = async function () {
274
+ await this._init();
296
275
  };
297
276
 
298
277
  /**
299
- * 初始化基础设施
278
+ * 初始化
300
279
  */
301
- Server.prototype._initModules = function () {
302
- // 模板引擎
303
- require('mm_tpl');
304
- const Http = require('mm_https').Http;
305
- $.Http = Http;
280
+ Server.prototype._init = async function () {
281
+ try {
282
+ // 初始化工具
283
+ this._initTool();
284
+ // 初始化基础设施
285
+ await this._initBase();
286
+ // 初始化模块
287
+ await this._initMod();
288
+ // 统一处理错误
289
+ this._initErrorRun();
290
+ } catch (error) {
291
+ this.log('error', '实例化失败:', error);
292
+ }
306
293
  };
307
294
 
308
295
  /**
309
296
  * 初始化基础设施
310
297
  */
311
298
  Server.prototype._initBase = function () {
299
+ // console.time('[TIMING] _initBase');
312
300
  // 获取数据库配置
313
301
  var sql = { type: 'mysql', ...this.config.sql };
314
302
  if (this.config.mysql) {
@@ -342,8 +330,8 @@ Server.prototype._initBase = function () {
342
330
  * 初始化工具
343
331
  */
344
332
  Server.prototype._initTool = function () {
345
- this.logger = new Log(this.config.log);
346
- $.log = this.logger;
333
+ $.log = new Log(this.config.log);
334
+ this.setLogger($.log);
347
335
  $.config = new Config({
348
336
  file: '/config.json'.fullname()
349
337
  });
@@ -354,245 +342,89 @@ Server.prototype._initTool = function () {
354
342
  $.com.loads();
355
343
  };
356
344
 
357
- /**
358
- * 初始化适配器
359
- */
360
- Server.prototype._initAdapter = async function () {
361
- // http服务器
362
- var web = new Web(this.config.web);
363
- web.init(this);
364
- this.adapter.web = web;
365
- if (this.config.web.socket) {
366
- // websocket服务器 - 与web服务器共享同一个端口
367
- this.adapter.ws = await new WebSocket(this.config.web).init(web);
368
- }
369
- if (this.config.mqtt && this.config.mqtt.state) {
370
- // mqtt服务器
371
- this.adapter.mqtt = await new Mqtt(this.config.mqtt).init(this.cache);
372
- }
373
- if (this.config.socket && this.config.socket.state) {
374
- // socket服务器
375
- this.adapter.socket = await new Socket(this.config.socket || {}).init();
376
- }
377
- };
378
-
379
-
380
- /**
381
- * 创建管理器实例
382
- * @param {string} name 管理器名称
383
- * @param {string} title 管理器标题
384
- * @param {Function} cls 管理器类
385
- * @returns {object} 管理器实例
386
- */
387
- Server.prototype._createManager = function (name, title, cls) {
388
- var manager = new Manager(
389
- {
390
- name: name,
391
- title: title,
392
- filename: name + '.json',
393
- tpl_dir: `./core/${name}/`.fullname(__dirname),
394
- base_dir: `./common/${name}/`.fullname(__dirname),
395
- dir: `./${name}`.fullname()
396
- },
397
- this,
398
- this[name],
399
- cls
400
- );
401
- // 设置到对应的管理器属性
402
- this.manager[name] = manager;
403
- return manager;
404
- }
405
-
406
- /**
407
- * 初始化管理
408
- */
409
- Server.prototype._initManager = async function () {
410
- // 管理器配置列表
411
- var mgrConfigs = [
412
- { name: 'game', title: '游戏', Module: Game },
413
- // { name: 'zone', title: '分区', Module: Zone },
414
- { name: 'app', title: '应用', Module: App },
415
- { name: 'mod', title: '模组', Module: Mod },
416
- { name: 'middleware', title: '中间件', Module: Middleware },
417
- { name: 'notifier', title: '通知器', Module: Notifier },
418
- { name: 'sender', title: '消息发送器', Module: Sender },
419
- { name: 'pusher', title: '广播器', Module: Pusher }
420
- ];
421
-
422
- // 管理器实例集合
423
- var managers = [];
424
-
425
- // 使用for循环初始化所有管理器
426
- for (var i = 0; i < mgrConfigs.length; i++) {
427
- var config = mgrConfigs[i];
428
- var manager = this._createManager(config.name, config.title, config.Module);
429
- managers.push(manager);
430
- }
431
-
432
- // 并行执行所有管理器的初始化操作
433
- var init_promises = [];
434
- for (var j = 0; j < managers.length; j++) {
435
- init_promises.push(managers[j].do('init'));
436
- }
437
-
438
- await Promise.all(init_promises);
439
- };
440
-
441
345
  /**
442
346
  * 初始化模块
443
347
  */
444
- Server.prototype._initAsyncMod = async function () {
445
- await Promise.all([
446
- this.manager.notifier.runAll('init', this.adapter, this.eventer, this.logger),
447
- this.manager.sender.runAll('init', this.adapter, this.eventer, this.logger),
448
- this.manager.pusher.runAll('init', this.adapter, this.eventer, this.logger)
449
- ]);
450
- this.manager.middleware.runWait('init', this.adapter, this.eventer, this.logger);
451
- };
348
+ Server.prototype._initMod = async function () {
349
+ // 模板引擎
350
+ require('mm_tpl');
351
+ const Http = require('mm_https').Http;
352
+ $.Http = Http;
452
353
 
453
- /**
454
- * 初始化资源
455
- */
456
- Server.prototype._initSources = async function () {
457
- // 初始化顺序 game > app > mod > middleware > notifier > sender > pusher,根据依赖关系自下而上初始化,内部并行执行
458
- await this.manager.game.runAll('init', this, this.eventer, this.logger);
459
- await this.manager.app.runAll('init', this, this.eventer, this.logger);
460
- await this.manager.mod.runAll('init', this, this.eventer, this.logger);
461
- await this._initAsyncMod();
354
+ // 初始化软件模块
355
+ this.software = new Software(this.config, this);
356
+ this.tpc = new TCP(this.config, this);
462
357
  };
463
358
 
464
359
  /**
465
- * 初始化
466
- * @private
360
+ * 启动
467
361
  */
468
- Server.prototype._init = async function () {
362
+ Server.prototype.start = async function () {
469
363
  try {
470
- // 初始化工具
471
- this._initTool();
472
- // 初始化模块
473
- this._initModules();
474
- // 初始化基础设施
475
- this._initBase();
476
- // 初始化适配器
477
- this._initAdapter();
478
- // 初始化管理器
479
- await this._initManager();
480
- // 加载资源
481
- await this._loadSources();
482
- // 初始化资源
483
- await this._initSources();
484
- // 统一处理错误
485
- this._initErrorRun();
364
+ if (this.status === 'created') {
365
+ await this.init();
366
+ }
367
+ await this._start();
368
+ this.log('info', '服务器启动成功');
486
369
  } catch (error) {
487
- this.log('error', '初始化过程失败:', error);
488
- throw error;
370
+ this.log('error', '服务器启动失败:', error);
489
371
  }
490
372
  };
491
373
 
492
374
  /**
493
- * 启动资源
375
+ * 启动
494
376
  */
495
- Server.prototype._startSources = async function () {
496
- // 启动无顺序,但需要等待所有启动完成,内部依次执行
377
+ Server.prototype._start = async function () {
497
378
  await Promise.all([
498
- this.manager.middleware.runAll('start'),
499
- this.manager.game.runAll('start'),
500
- // this.manager.zone.runAll('start'),
501
- this.manager.app.runAll('start'),
502
- this.manager.mod.runAll('start')
379
+ // 连接缓存数据库
380
+ $.cache.connect(),
381
+ // 打开数据库连接
382
+ $.sql.open()
503
383
  ]);
384
+ // 运行模块
385
+ await this._runMod();
504
386
  };
505
387
 
506
388
  /**
507
- * 启动适配器
508
- */
509
- Server.prototype._startAdapter = async function () {
510
- for (var k in this.adapter) {
511
- try {
512
- await this.adapter[k].start();
513
- } catch (error) {
514
- this.log('error', '启动适配器失败:', error);
515
- }
516
- }
517
- };
518
-
519
- /**
520
- * 停止适配器
389
+ * 运行模块
521
390
  */
522
- Server.prototype._stopAdapter = async function () {
523
- for (var k in this.adapter) {
524
- try {
525
- await this.adapter[k].stop();
526
- } catch (error) {
527
- this.log('error', '停止适配器失败:', error);
528
- }
529
- }
391
+ Server.prototype._runMod = async function () {
392
+ await Promise.all([,
393
+ // 启动TCP
394
+ this.tpc.run(),
395
+ // 启动软件
396
+ this.software.run()
397
+ ]);
530
398
  };
531
399
 
532
400
  /**
533
401
  * 停止
534
402
  */
535
- Server.prototype._stop = async function () {
536
- await this._stopAdapter();
537
- };
538
-
539
- /**
540
- * 启动
541
- */
542
- Server.prototype._start = async function () {
543
- $.sql.open();
544
- $.cache.connect();
545
-
546
- // 启动资源
547
- await this._startSources();
548
-
549
- // 启动适配器
550
- await this._startAdapter();
403
+ Server.prototype.stop = async function () {
404
+ await this._stop();
551
405
  };
552
406
 
553
407
  /**
554
- * 加载资源
408
+ * 停止 - 私有方法
555
409
  */
556
- Server.prototype._loadSources = async function () {
557
- // 加载无需依赖关系,所以可以同时加载,内部并行执行
410
+ Server.prototype._stop = async function () {
558
411
  await Promise.all([
559
- this.manager.game.runAll('load'),
560
- // this.manager.zone.runAll('load'),
561
- this.manager.app.runAll('load'),
562
- this.manager.middleware.runAll('load'),
563
- this.manager.mod.runAll('load')
412
+ // 关闭数据库连接
413
+ $.sql.close(),
414
+ // 停止资源
415
+ $.cache.close()
564
416
  ]);
565
417
  };
566
418
 
567
419
  /**
568
- * 启动服务器
420
+ * 运行
569
421
  */
570
- Server.prototype.start = async function () {
571
- try {
572
- if (this.status === 'created') {
573
- await this.init();
574
- }
575
- await this._start();
576
- this.log('info', '服务器启动成功');
577
- } catch (error) {
578
- this.log('error', '服务器启动失败:', error);
579
- throw error;
580
- }
581
- };
582
-
583
- /**
584
- * 初始化全局错误处理机制
585
- */
586
- Server.prototype._initErrorRun = function () {
587
- // 全局未捕获异常处理
588
- process.on('uncaughtException', (error) => {
589
- this.log('error', '全局未捕获异常:', error);
590
- });
591
-
592
- // 全局未处理Promise拒绝处理
593
- process.on('unhandledRejection', (reason) => {
594
- this.log('error', '全局未处理Promise拒绝:', reason);
595
- });
422
+ Server.prototype.run = async function () {
423
+ // 初始化
424
+ await this.init();
425
+ // 启动
426
+ await this.start();
427
+ return this;
596
428
  };
597
429
 
598
430
  exports.Server = Server;