mm_os 4.0.9 → 4.1.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.
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,48 @@ 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
+ // 初始化工具
282
+ this._initTool();
283
+ // 初始化基础设施
284
+ this._initBase();
285
+ // 初始化模块
286
+ this._initMod();
287
+ // 统一处理错误
288
+ this._initErrorRun();
306
289
  };
307
290
 
308
291
  /**
309
292
  * 初始化基础设施
310
293
  */
311
294
  Server.prototype._initBase = function () {
295
+ // console.time('[TIMING] _initBase');
312
296
  // 获取数据库配置
313
297
  var sql = { type: 'mysql', ...this.config.sql };
314
298
  if (this.config.mysql) {
@@ -342,8 +326,8 @@ Server.prototype._initBase = function () {
342
326
  * 初始化工具
343
327
  */
344
328
  Server.prototype._initTool = function () {
345
- this.logger = new Log(this.config.log);
346
- $.log = this.logger;
329
+ $.log = new Log(this.config.log);
330
+ this.setLogger($.log);
347
331
  $.config = new Config({
348
332
  file: '/config.json'.fullname()
349
333
  });
@@ -354,245 +338,89 @@ Server.prototype._initTool = function () {
354
338
  $.com.loads();
355
339
  };
356
340
 
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
341
  /**
442
342
  * 初始化模块
443
343
  */
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
- };
344
+ Server.prototype._initMod = function () {
345
+ // 模板引擎
346
+ require('mm_tpl');
347
+ const Http = require('mm_https').Http;
348
+ $.Http = Http;
452
349
 
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();
350
+ // 初始化软件模块
351
+ this.software = new Software(this.config, this);
352
+ this.tpc = new TCP(this.config, this);
462
353
  };
463
354
 
464
355
  /**
465
- * 初始化
466
- * @private
356
+ * 启动
467
357
  */
468
- Server.prototype._init = async function () {
358
+ Server.prototype.start = async function () {
469
359
  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();
360
+ if (this.status === 'created') {
361
+ await this.init();
362
+ }
363
+ await this._start();
364
+ this.log('info', '服务器启动成功');
486
365
  } catch (error) {
487
- this.log('error', '初始化过程失败:', error);
488
- throw error;
366
+ this.log('error', '服务器启动失败:', error);
489
367
  }
490
368
  };
491
369
 
492
370
  /**
493
- * 启动资源
371
+ * 启动
494
372
  */
495
- Server.prototype._startSources = async function () {
496
- // 启动无顺序,但需要等待所有启动完成,内部依次执行
373
+ Server.prototype._start = async function () {
497
374
  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')
375
+ // 连接缓存数据库
376
+ $.cache.connect(),
377
+ // 打开数据库连接
378
+ $.sql.open()
503
379
  ]);
380
+ // 运行模块
381
+ await this._runMod();
504
382
  };
505
383
 
506
384
  /**
507
- * 启动适配器
385
+ * 运行模块
508
386
  */
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
- * 停止适配器
521
- */
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
- }
387
+ Server.prototype._runMod = async function () {
388
+ await Promise.all([
389
+ // 启动TCP
390
+ this.tpc.run(),
391
+ // 启动软件
392
+ this.software.run()
393
+ ]);
530
394
  };
531
395
 
532
396
  /**
533
397
  * 停止
534
398
  */
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();
399
+ Server.prototype.stop = async function () {
400
+ await this._stop();
551
401
  };
552
402
 
553
403
  /**
554
- * 加载资源
404
+ * 停止 - 私有方法
555
405
  */
556
- Server.prototype._loadSources = async function () {
557
- // 加载无需依赖关系,所以可以同时加载,内部并行执行
406
+ Server.prototype._stop = async function () {
558
407
  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')
408
+ // 关闭数据库连接
409
+ $.sql.close(),
410
+ // 停止资源
411
+ $.cache.close()
564
412
  ]);
565
413
  };
566
414
 
567
415
  /**
568
- * 启动服务器
416
+ * 运行
569
417
  */
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
- });
418
+ Server.prototype.run = async function () {
419
+ // 初始化
420
+ await this.init();
421
+ // 启动
422
+ await this.start();
423
+ return this;
596
424
  };
597
425
 
598
426
  exports.Server = Server;