pomelo之application的创建于初始化

《断网不丢日志,多机共享工单:高速龙门贴片机实战沉淀 SQLite + MySQL 双库分层架构实战-无硬件 Mock 可直接运行》 本文介绍了一个工业设备管理系统的双数据库架构设计,核心采用SQLite存储本地日志,MySQL存储生产数据。系统基于WPF框架,使用MVVM模式和EF Core实现数据持久化。实现细节: 通过DI容器注册双DbContext 日志异步写入不阻塞UI 提供模拟/真机两种运行模式 支持EF迁移命令初始化数据库 阅读详情

距离上一篇pomelo已经有一段时间了吧,总是有一些事情要做。。

这一篇来写pomelo的application的创建过程。。当然例子还是以官方的chat。。。。主要是来分析下面这段代码:

var app = pomelo.createApp();

我们首先来看看pomelo的定义吧:

var fs = require('fs');
var path = require('path');
var application = require('./application');


/**
 * Expose `createApplication()`.
 *
 * @module
 */
//这里相当于是进行命名
var Pomelo = module.exports = {};

/**
 * Framework version.
 */

Pomelo.version = '0.4';

/**
 * Event definitions that would be emitted by app.event
 */
Pomelo.events = require('./util/events');

/**
 * auto loaded components
 */
 //用于保存组件
Pomelo.components = {};

/**
 * auto loaded filters
 */
 //用于保存filter
Pomelo.filters = {};

/**
 * connectors
 */
 //connector对象
Pomelo.connectors = {};
//connector对象的get方法
Pomelo.connectors.__defineGetter__('sioconnector', function() {
  return require('./connectors/sioconnector');
});
//超级connector的get方法
Pomelo.connectors.__defineGetter__('hybridconnector', function() {
  return require('./connectors/hybridconnector');
});

/**
 * schedulers
 */
 //定义调度器
Pomelo.schedulers = {};
Pomelo.schedulers.__defineGetter__('direct', function() {
  var m = require('./scheduler/direct');
  return m;
});

Pomelo.schedulers.__defineGetter__('buffer', function() {
  return require('./scheduler/buffer');
});

/**
 * global channel manager
 */
Pomelo.connectors.__defineGetter__('redisGlobalChannelManager', function() {
  return require('./common/manager/redisGlobalChannelManager');
});

//用self来指向当前的作用域
var self = this;

/**
 * Create an pomelo application.
 *
 * @return {Application}
 * @memberOf Pomelo
 * @api public
 */
 //创建application对象
Pomelo.createApp = function (opts) {
  var app = application;
  app.init(opts);  //初始化函数
  self.app = app;
  return app;
};

/**
 * Get application
 */
 //相当于是为Pomelo对象添加一个属性,app,它是一个对象,就存在一个get方法,用于返回当前的app对象
Object.defineProperty(Pomelo, 'app', {
  get:function () {
    return self.app;
  }
});

/**
 * Auto-load bundled components with getters.
 */
 //用于在components文件夹中读取组件,然后保存到components对象里面去
fs.readdirSync(__dirname + '/components').forEach(function (filename) {
  if (!/\.js$/.test(filename)) {
    return;
  }
  var name = path.basename(filename, '.js');

  function load() {
    return require('./components/' + name);
  }
  Pomelo.components.__defineGetter__(name, load);//例如执行Pomelo.components.aa,其实会得到require("./components/aa");的值
  Pomelo.__defineGetter__(name, load);
});

//用于读取filter对象
fs.readdirSync(__dirname + '/filters/handler').forEach(function (filename) {
  if (!/\.js$/.test(filename)) {
    return;
  }
  var name = path.basename(filename, '.js');

  function load() {
    return require('./filters/handler/' + name);
  }
  Pomelo.filters.__defineGetter__(name, load);
  Pomelo.__defineGetter__(name, load);
});
其实本身pomelo的定义还是很简单的,无非就是定义了一些名字,然后加载了一些组件,这里其实可以将pomelo对象看成已是一个资源的管理。。。

这里大量用到了如下的方法:

Pomelo.connectors.__defineGetter__('redisGlobalChannelManager', function() {
  return require('./common/manager/redisGlobalChannelManager');
});
这种用法其实就是定义一下这个属性的获取方法,当Pomelo.connectors.redisGlobalChannelManager的方式访问这个属性的时候,会直接调用换进去的函数,得到返回值。。。

我们重点来分析如下代码:

 //创建application对象
Pomelo.createApp = function (opts) {
  var app = application;
  app.init(opts);  //初始化函数
  self.app = app;
  return app;
};
由于application的定义比较长,就不一次性列出来,先来看看它的init方法。。。。
Application.init = function(opts) {
  opts = opts || {};
  this.loaded = [];       // loaded component list
  //用于保存所有的组件
  this.components = {};   // name -> component map

  //调用set方法保存的参数将会保存在这个地方
  this.settings = {};     // collection keep set/get
  this.set('base', opts.base);
  //事件对象
  this.event = new EventEmitter();  // event object to sub/pub events

  // current server info
  this.serverId = null;   // current server id
  this.serverType = null; // current server type
  this.curServer = null;  // current server info

  // global server infos
  this.master = null;         // master server info
  //用于保存所有的server,id与info的键值对
  this.servers = {};          // current global server info maps, id -> info
  this.serverTypeMaps = {};   // current global type maps, type -> [info]
  this.serverTypes = [];      // current global server type list

  appUtil.defaultConfiguration(this);   //默认配置

  this.state = STATE_INITED;  //将当前的状态修改为已经初始化
  logger.info('application inited: %j', this.getServerId());
};
刚开始启动的视乎,没有参数传进来,opts就是null,代码本身也很简单吧,可以当做是对application对象的一些属性的声明和初始化。。。

这里主要是要看一下defaultConfiguration部分干了些什么。。。

我们来看看它的定义吧:

module.exports.defaultConfiguration = function (app) {
  var args = parseArgs(process.argv);  //这里process.argv保存的是运行使用的命令,是一个数组例如[ 'node', '/home/fjs/Desktop/pomelo/game-server/app.js' ]
  /*
  [ '/usr/local/bin/node',
  '/home/fjs/Desktop/pomelo/game-server/app.js',
  'env=development',
  'id=chat-server-2',
  'host=127.0.0.1',
  'port=6051',
  'serverType=chat' ]
*/

  //最后args如以下形式:
  //master { main: '/home/fjs/Desktop/pomelo/game-server/app.js' }

  /*{ main: '/home/fjs/Desktop/pomelo/game-server/app.js',
  env: 'development',
  id: 'connector-server-1',
  host: '127.0.0.1',
  port: 4050,
  clientPort: 3050,
  frontend: 'true',
  serverType: 'connector' }*/

  setupEnv(app, args);    //设置当前环境的配置,是开发,部署等
  loadMaster(app);    //加载master服务器的配置
  loadServers(app);   //加载server的配置
  processArgs(app, args);
  configLogger(app);
};
代码还是很简单吧,先是获取当前的执行命令,例如:node app.js,

然后对其进行一些处理,将一些参数处理出来,这里可能要分为两种,毕竟有master服务器和非master服务器。。。他们解析出来的结果在上面的注释都已经标了出来。。。

接下来就是设置环境,例如是development或者production。。。

然后载入Master服务器的配置,然后载入普通server的配置。。。

这里我们就选一个出来看看吧,看看普通server的配置是怎么进行载入的。。。

var loadServers = function(app) {
  app.loadConfig('servers', app.getBase() + '/config/servers.json');  //载入server类型的服务器的配置
  var servers = app.get('servers');   //获取刚刚载入的配置信息
  var serverMap = {}, slist, i, l, server;
  for(var serverType in servers) {   //遍历serve的类型,chat,gate,connector
    slist = servers[serverType];
    for(i=0, l=slist.length; i<l; i++) {    //遍历当前这种类型的server
      server = slist[i];
      server.serverType = serverType;
      serverMap[server.id] = server;   //将这些server保存到serverMap里面去

      if(server.wsPort) {
        logger.warn('wsPort is deprecated, ' +
                    'use clientPort and frontend instead.');
      }
    }
  }

  app.set('__serverMap__', serverMap);  //将所有的server保存到app域里去
};
代码还是很简单的吧,首先载入配置文件,然后遍历其中server类型,然后将他们用键值对管理起来就完事了。。。

额。。

最后还有一个  processArgs(app, args);

var processArgs = function(app, args){
  var serverType = args.serverType || 'master';   //如果没有serverType,那么就是master服务器了
  var serverId = args.id || app.getMaster().id;    //获取服务器的id

  app.set('main', args.main, true);    //将运行信息保存起来,
    //master { main: '/home/fjs/Desktop/pomelo/game-server/app.js' }

  /*{ main: '/home/fjs/Desktop/pomelo/game-server/app.js',
  env: 'development',
  id: 'connector-server-1',
  host: '127.0.0.1',
  port: 4050,
  clientPort: 3050,
  frontend: 'true',
  serverType: 'connector' }*/
  app.set('serverType', serverType, true);
  app.set('serverId', serverId, true);

 if(serverType !== 'master') {  //保存当前服务器类型
    app.set('curServer', args, true);
  } else {
    app.set('curServer', app.getMaster(), true);   
  }
};
其实这个名字有点唬人,并没有执行什么命令,无非是设置了一些参数而已,。。。。。


好了,那么整个application的创建过程就差不多了,其实这部分最主要的事情还是将配置文件load进来。。。


下一篇来分析一下启动过程吧。。。。

C#学习笔记-MySql.EntityFrameworkCore数据库配置 Entity Framework Core基础操作学习,包括怎么搭建,以及应用迁移,和部分基础使用的注意事项,可以快速走同一个应用程序,适合快速开始。 阅读详情

相关推荐

ASP.NET Core Web API后端开发:基于EFCore与MySQL的分层架构实践

在Web开发领域,构建健壮的后端服务是支撑各类应用的核心。其原理在于通过清晰的分层架构实现关注点分离,从而提升代码的可维护性和可测试性。这一技术价值体现在能够高效处理业务逻辑、数据持久化和API交互,广泛应用于企业内部系统、移动应用后端及互联网服务。具体到.NET技术栈,ASP.NET Core作为跨平台的高性能框架,结合Entity Framework Core(EFCore)这一ORM工具,可以大幅简化数据库操作。通过仓储模式和工作单元模式,开发者能以面向对象的方式操作MySQL等关系型数据库,实现数据

weixin_33404102的博客 261

Pomelo Application

应用程序配置,如何配置Pomelo框架? Pomelo可以配置各个组件的选项,加载配置文件,开启Pomelo的特性等,这些配置都是在game-server/app.js文件中进行的。实际上在Pomelo的应用中有两个app.js,一个是在game-server目录下,一个是在web-server目录下。game-server下的app.js是整个游戏服务器的入口和配置点。web-server下的...

嘿嘿 559

ASP.NET Core Web API + EF Core + MySQL 实战:从环境搭建到部署上线的完整指南

在构建现代Web应用后端时,对象关系映射(ORM)技术是连接应用程序与数据库的关键桥梁,它通过将数据库表映射为编程语言中的对象,简化了数据访问层的开发。Entity Framework Core作为.NET生态中主流的ORM框架,其核心原理在于提供了一种声明式的数据操作方式,开发者可以使用LINQ进行查询,EF Core会将其转换为高效的SQL语句。这种技术价值在于大幅提升了开发效率,降低了数据库操作的复杂度,并保证了类型安全。在实际应用中,EF Core常与ASP.NET Core Web API结合,用

weixin_31236101的博客 365

pomelo使用采坑记(学习使用部署相关)

pomelo学习、使用和部署pomelo推送方式频道推送直接推送bearcat集成remote和handler集成非pomelo框架的service、util等的集成bearcat优势默认路由规则采坑未进行用户Id绑定的多服务器远程调用路由配置log按照时间日期服务器分割按服务器和天分割按服务端和小时分割按天分割IDEA调式服务器配置IDEA配置步骤分布式部署ssh方式非ssh方式 pomelo推...

tqy的博客 4110

微信小程序转化数据API自归因实战:PHP实现与2025升级要点解析

本文详细解析了2025年微信小程序转化数据API自归因的升级要点与PHP实战实现。核心变化包括接口地址更新、固定access_token的获取方式,以及新增timestamp与nonce等安全参数。文章提供了完整的PHP代码示例,帮助开发者高效完成数据上报,优化腾讯广告投放效果。

git9versioner的博客 989

基于Matlab的MIMO通信系统仿真_Simulink实现

瑞利衰落信道中使用空时分组码的BPSK调制的BER 1、2发1收 参数设置: 双极性信号元+1和-1,每符号含1bit; 采样时间=符号时间=1s; 采用基于数据帧的仿真计算模式,每帧中有2个采样值; 仿真时间=出现100个误码后停止仿真; 随机整数种子=22; Jakes衰落模型中每个信道上的多普勒频移=0.01Hz; 输人信号功率=2W; Alamouti码:两根发送天线,一根接收天线(分集阶= 2); 平均信道信噪比= 18dB; 仿真得出的误码率统计BER =0. 00017. 2、2发

太阳帅帅的博客 9688

Pomelo框架总结

Pomelo框架总结 A fast,scalable,distributed game server framework for Node.js 联系我 Pomelo交流群 @老顽童-NextZeus 微信群 BJ NodeJS Club @老顽童 适用场景 多人游戏:手游,社交游戏,网页游戏,MMORPG ,ARPG 实时应用:聊天,消息推送,等等 特点 高性能:基于Node.js...

嘿嘿 2185

M系列芯片MacBook上UTM虚拟机部署达梦DM8的避坑指南

本文详细介绍了在M系列芯片MacBook上使用UTM虚拟机部署达梦数据库DM8的完整流程与避坑指南。针对ARM架构环境,重点解决了虚拟机选择、麒麟系统安装、系统调优及DM8命令行安装中的常见问题,为开发者提供了稳定可靠的国产数据库本地测试方案。

weixin_28455801的博客 456

pomelo应用程序配置

在这部分,我们来介绍如何配置框架。我们知道在pomelo中,可以配置各个组件的选项,加载配置文件,开启pomelo的特性等等。这一切配置都是在game-server/app.js中进行的。实际上,在pomelo的应用中有两个app.js,一个在game-server目录下,一个在web-server目录下。其中game-server下的app.js是整个游戏服务器的入口和配置点,而web-serv...

疯狂的程序员 813

Globus 数据下载

Globus 大数据下载流程~

weixin_43978558的博客 6628

记录一次Spring Framework 漏洞修复的过程

摘要:针对Spring Boot 2.6.13项目在阿里云漏洞扫描中发现的Spring Framework目录遍历漏洞(CVE-2024-38819),首先分析了漏洞成因,确认5.3.23版本存在风险。解决方案包括升级Spring Boot至2.7.18(对应Spring Framework 5.3.41)或6.0+版本,但后者需JDK17支持。临时方案通过配置HttpFirewall限制特殊字符,最终借助阿里云防护服务暂时解决问题。建议长期解决方案仍需升级至安全版本(Spring Boot 6.1.14或

极客栈 1489

【Pomelo源码分析】2016-09-21 程序入口(app.js, pomelo.js, application.js)

Pomelo程序入口,app.js、pomelo.js、application.js文件的源码分析

u010334580的博客 1875

安装openclaw时出现npm error code ENOENT npm error syscall spawn git报错的解决方案

本文主要介绍了安装openclaw时出现npm error code ENOENT npm error syscall spawn git报错的解决方案,希望能对使用openclaw的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案

weixin_43178406的博客 12万+

pomelo 框架第一部分 pomelo框架基础

pomelo 框架第一部分 项目地址: https://github.com/NetEase/chatofpomelo-websocket.git 一、pomelo.js pomelo.js中的初始化 Pomelo.connectors = {}; Pomelo.connectors.__defineGetter__('sioconnector', load.bind(null, './connectors/sioconnector')); Pomelo.connectors.__defineGetter_

ai_milk的博客 1694

5、快速入门

点击启动实例按钮,并设计一个business key,每个实例会有一个business key, 业务主键,也相当于一个流程实例唯一key,一般会与一次业务强相关,比如一个订单号 ,此处取为shopping_1;付款程序完成后会流转到物流发货任务,此时java工程的相应订阅会收到任务,并进入断点,且读到到toWhere变量。单击shopping可以进入实时流程图的执行图,此时流程流转到第一个任务,需要业务系统完成此任务,并通知引擎。添加类,分别订阅流程中的加入购物车任务和物流发货任务。

leyoliu的博客 3501

嵌入式系统开发笔记112:通过有人云测试MQTT

项目中使用到“有人”公司的WH-LTE-7S0模块,本文讲解通过有人云进行MQTT测试的方法。

snmplink的博客 999

Pomelo之application的start

 这篇文章要分析如下部分的代码: [javascript] view plaincopyprint? // app configure  app.configure('production|development', function() {      // route configures      app.route('chat', routeUtil.chat)

lisaem的专栏 945

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

pomelo之server的启动。。

前面的一片文章分析了master服务器的启动: 主要就是载入和启动组件,而且master的具体工作还是在其的console,对于master究竟在干些什么东西,并没有看的太多,以后涉及到了再细看吧。。那么这篇文章就来看看其余的server是怎么启动的,顺便还要看看他们是怎么进行工作的。。。。 好吧,还是首先从application的创建开始吧: Pomelo.createApp = ...

嘿嘿 693

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Pomelo 新手入门(一)

Pomelo 新手入门(一) 前言 由于目前pomelo公开资料没有什么教程类的,打算花一周时间学习一下pomelo.所以就简单的写个学习笔记,用来记录一下。 应该会有7篇,这篇应该是星期一学习的量,由于各种原因,总结慢了。。。 通读api 个人认为,竟然要使用一个框架,对于框架提供的api必须要烂熟与心,pomelo的api 还是挺少的,所以量化一下,让初学者感觉读

zhou_xtao的专栏 8871

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Pomelo 学习笔记

写在前面   这几天由于公司需要自己开发一个手机APP的推送,经过一番查找发现有pomelo这么一个框架,在做了一定了解后,决定先搭一个测试环境试一试。   先贴一个Pomelo在github上的地址https://github.com/NetEase/pomelo/wiki/Home-in-Chinese   关于Pomelo开发环境的搭建我在这就不复述了,在《pomelo快速

zhoujianghua_2008的专栏 974

pomelo 初始化配置...

在创建app的时候会初始化master和server以及log配置.. /** * Initialize application configuration. */ module.exports.defaultConfiguration = function(app) { var args = parseArgs(process.argv); setupEnv(app,...

weixin_34009794的博客 192

pomelo源码解析之compnent组件启动

pomelo中的各个功能模块都是以component组件的形式封装的。例如sessionService,channelService等等。 接下来我们来看component如何被启动,废话不多说,直接上源码。Application.start = function(cb) { this.startTime = Date.now(); if(this.state > STATE_INITED

u012714981的专栏 1109

游戏服务器架构设计:从技术选型到高并发实战全解析

游戏服务器架构是支撑多人在线游戏稳定运行的核心技术体系。其基本原理是通过模块化设计将网关、逻辑、匹配、战斗等不同功能解耦,采用分布式部署应对高并发场景。这种架构的价值在于能够实现水平扩展,保证游戏服务的稳定性和可维护性。在实际应用中,基于Netty的高性能网络通信框架配合Spring Boot的业务逻辑处理,构成了现代游戏服务器的技术基石。通过合理的数据库选型与缓存策略,结合Docker容器化部署,可以构建出能够支撑大规模玩家同时在线的游戏后端系统。本文聚焦游戏服务器开发全流程,深入解析高并发架构设计、实时

weixin_34319374的博客 397

.NET三层架构:为什么它仍是现代应用开发的坚实底座

分层架构是一种将系统按职责划分为表现层、业务逻辑层和数据访问层的基础软件设计思想,其核心原理在于通过明确责任边界实现松耦合与高内聚。这种设计显著提升系统的可测试性、可维护性和团队协作效率,尤其在中大型企业级应用中,能有效控制重构成本并支撑渐进式演进。在.NET生态中,三层架构凭借对EF Core、ASP.NET Core等技术的天然适配性,成为微服务落地前不可或缺的单体治理基础。本文聚焦.NET平台下的三层实践,深入解析表现层契约设计、业务逻辑层规则封装、数据访问层抽象策略,以及如何规避紧耦合、SQL注入、

442
上一篇: TCP/IP之buff分析m_buff与sk_buff
下一篇: Pomelo之application的start
fjs_cloud
博客等级 码龄15年 248粉丝 192原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值