千里之行始於足下,一直說想了解pomelo,對pomelo有興趣,但一直遲遲沒有去碰,儘管對pomelo進行源代碼分析,在網絡上確定不止我一個,已經有很是優秀的前輩走在前面,如http://golanger.cn/,在閱讀Pomelo代碼的時候,已經連載到了11篇了,在個人源代碼分析參考了該博客,固然,也會添�我對pomelo的理解,藉此但願能提升一下本身對node.js的瞭解和學習一些優秀的設計。javascript
{ "name": "chatofpomelo", "version": "0.0.1", "private": false, "dependencies": { "pomelo": "0.2.0", "log4js": ">= 0.4.1", "crc": ">=0.0.1" } }
gameserver/app.jsjava
var pomelo = require('pomelo'); var routeUtil = require('./app/util/routeUtil'); /** * Init app for client. */ var app = pomelo.createApp(); //建立Application app.set('name', 'chatofpomelo'); //設置Application名字 // app configure app.configure('production|development', function() { // route configures app.route('chat', routeUtil.chat); // filter configures app.filter(pomelo.timeout()); }); // start app app.start(); process.on('uncaughtException', function(err) { console.error(' Caught exception: ' + err.stack); });
var opt = {'base':'D:\\src\\pomelo\\chatofpomelo\\game-server'} var app = pomelo.createApp(opt); app.set('name', 'chatofpomelo');
app.js 是game-server的主要入口,主要負責建立application,讀取配置文件,應用到application設置上,並利用app.start()來運行實際的master,monitor等服務器的start,對於聊天室程序來講,還要作簡單的路由和過濾設置。node
application, 應用的定義、component管理,上下文配置, 這些使pomelo framework的對外接口很是easy, 並且具備鬆耦合、可插拔架構。
golang
所有server的啓動都是從執行app.js開始。每一個server的啓動都首先建立一個全局惟一的application對象,該對象中掛載了所在server的所有信息,包含server物理信息、server邏輯信息、以及pomelo的組件信息等。同一時候,該對象還提供應用管理和配置等基本方法。 在app.js中調用app.start()方法後,application對象首先會經過loadDefaultComponents方法載入默認的組件。web
pomelo/lib/pomelo.js
json
var application = require('./application'); Pomelo.createApp = function (opts) { var app = application; app.init(opts); self.app = app; return app; };
/** * Application prototype. * * @module */ var Application = module.exports = {}; /** * Application states */ var STATE_INITED = 1; // app has inited var STATE_START = 2; // app start var STATE_STARTED = 3; // app has started var STATE_STOPED = 4; // app has stoped /** * Initialize the server. * * - setup default configuration * * @api private */ Application.init = function(opts) { opts = opts || {}; logger.info('app.init invoked'); this.loaded = []; this.components = {}; this.settings = {}; // set,和get功能的容器 this.set('base', opts.base); //設置服務器的工做文件夾 this.defaultConfiguration(); //依據配置文件,載入master,monitor等服務器 this.state = STATE_INITED; //application工做狀態 logger.info('application inited: %j', this.get('serverId')); };
/** * Initialize application configuration. * * @api private */ Application.defaultConfiguration = function () { var args = utils.argsInfo(process.argv); this.setupEnv(args); //application環境設置 this.loadServers(); //載入server配置信息 this.loadConfig('master', this.getBase() + '/config/master.json'); //載入materserver配置信息 this.processArgs(args); //依據啓動參數設定server配置 this.configLogger(); };
啓動game-server服務器:>pomelo start [development | production] [--daemon]
api
依據args參數設定application的工做環境是development或production服務器
/** * Setup enviroment. * @api private */ Application.setupEnv = function(args) { this.set('env', args.env || process.env.NODE_ENV || 'development', true); };
/** * Load server info from configure file. * * @api private */ Application.loadServers = function() { this.loadConfig('servers', this.getBase() + '/config/servers.json'); var servers = this.get('servers'); var serverMap = {}, slist, i, l, server; for(var serverType in servers) { slist = servers[serverType]; for(i=0, l=slist.length; i<l; i++) { server = slist[i]; server.serverType = serverType; serverMap[server.id] = server; } } this.set('__serverMap__', serverMap); };
{ "development":{ "connector":[ {"id":"connector-server-1", "host":"127.0.0.1", "port":4050, "wsPort":3050}, {"id":"connector-server-2", "host":"127.0.0.1", "port":4051, "wsPort":3051}, {"id":"connector-server-3", "host":"127.0.0.1", "port":4052, "wsPort":3052} ], "chat":[ {"id":"chat-server-1", "host":"127.0.0.1", "port":6050}, {"id":"chat-server-2", "host":"127.0.0.1", "port":6051}, {"id":"chat-server-3", "host":"127.0.0.1", "port":6052} ], "gate":[ {"id": "gate-server-1", "host": "127.0.0.1", "wsPort": 3014} ] }, "production":{ "connector":[ {"id":"connector-server-1", "host":"127.0.0.1", "port":4050, "wsPort":3050}, {"id":"connector-server-2", "host":"127.0.0.1", "port":4051, "wsPort":3051}, {"id":"connector-server-3", "host":"127.0.0.1", "port":4052, "wsPort":3052} ], "chat":[ {"id":"chat-server-1", "host":"127.0.0.1", "port":6050}, {"id":"chat-server-2", "host":"127.0.0.1", "port":6051}, {"id":"chat-server-3", "host":"127.0.0.1", "port":6052} ], "gate":[ {"id": "gate-server-1", "host": "127.0.0.1", "wsPort": 3014} ] } }
工具函數,讀取json配置文件,在這裏讀取的是master.json文件網絡
/** * Load Configure json file to settings. * * @param {String} key environment key * @param {String} val environment value * @return {Server|Mixed} for chaining, or the setting value * * @memberOf Application */ Application.loadConfig = function (key, val) { var env = this.get('env'); val = require(val); if (val[env]) { val = val[env]; } this.set(key, val); };
{ "development":{ "id":"master-server-1", "host":"127.0.0.1", "port":3005, "queryPort":3015, "wsPort":2337 }, "production":{ "id":"master-server-1", "host":"127.0.0.1", "port":3005, "queryPort":3015, "wsPort":2337 } }
Application.processArgs = function(args){ var serverType = args.serverType || 'master'; var serverId = args.serverId || this.get('master').id; this.set('main', args.main, true); this.set('serverType', serverType, true); this.set('serverId', serverId, true); if(serverType !== 'master') { this.set('curServer', this.getServerById(serverId), true); } else { this.set('curServer', this.get('master'), true); } };
Application.configLogger = function() { if(process.env.POMELO_LOGGER !== 'off') { log.configure(this, this.getBase() + '/config/log4js.json'); } };
{ "appenders": [ { "type": "file", "filename": "./logs/node-log-${opts:serverId}.log", "fileSize": 1048576, "layout": { "type": "basic" }, "backups": 5 }, { "type": "console" }, { "type": "file", "filename": "./logs/con-log-${opts:serverId}.log", "pattern": "connector", "fileSize": 1048576, "layout": { "type": "basic" } ,"backups": 5, "category":"con-log" }, { "type": "file", "filename": "./logs/rpc-log-${opts:serverId}.log", "fileSize": 1048576, "layout": { "type": "basic" } ,"backups": 5, "category":"rpc-log" }, { "type": "file", "filename": "./logs/forward-log-${opts:serverId}.log", "fileSize": 1048576, "layout": { "type": "basic" } ,"backups": 5, "category":"forward-log" }, { "type": "file", "filename": "./logs/crash.log", "fileSize": 1048576, "layout": { "type": "basic" } ,"backups": 5, "category":"crash-log" } ], "levels": { "rpc-log" : "ERROR", "forward-log": "ERROR" }, "replaceConsole": true }