zoukankan      html  css  js  c++  java
  • pomelo源代码分析(一)

            千里之行始于足下,一直说想了解pomelo,对pomelo有兴趣,但一直迟迟没有去碰,尽管对pomelo进行源代码分析,在网络上肯定不止我一个,已经有非常优秀的前辈走在前面,如http://golanger.cn/,在阅读Pomelo代码的时候,已经连载到了11篇了,在我的源代码分析參考了该博客,当然,也会添�我对pomelo的理解,借此希望能提高一下自己对node.js的了解和学习一些优秀的设计。

    • 开发环境:win7
    • 调试环境:webstorm5.0
    • node.js版本号:v0.8.21
    • 源代码版本号package.json:

    {
    	"name": "chatofpomelo",
    	"version": "0.0.1",
    	"private": false,
    	"dependencies": {
    		"pomelo": "0.2.0",
    		"log4js": ">= 0.4.1",
    		"crc": ">=0.0.1"
    	}
    }

    gameserver/app.js

    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);
    });

    注意:在webstorm下调试,可能由于工作文件夹的设置原因会导致应用的运行路径问题,导致无法读取配置文件,所以须要依据实际情况改动例如以下

    var opt = {'base':'D:\src\pomelo\chatofpomelo\game-server'}
    var app = pomelo.createApp(opt);
    app.set('name', 'chatofpomelo');

    opt.base 是你的game-server的实际文件夹路径,详细能够依据自己须要来定制

    app.js 是game-server的主要入口,主要负责创建application,读取配置文件,应用到application设置上,并利用app.start()来运行实际的master,monitor等服务器的start,对于聊天室程序来说,还要做简单的路由和过滤设置。


    application, 应用的定义、component管理,上下文配置, 这些使pomelo framework的对外接口非常easy, 而且具有松耦合、可插拔架构。

    全部server的启动都是从执行app.js開始。每个server的启动都首先创建一个全局唯一的application对象,该对象中挂载了所在server的全部信息,包含server物理信息、server逻辑信息、以及pomelo的组件信息等。同一时候,该对象还提供应用管理和配置等基本方法。 在app.js中调用app.start()方法后,application对象首先会通过loadDefaultComponents方法载入默认的组件。


    pomelo/lib/pomelo.js

    var application = require('./application');
    
    Pomelo.createApp = function (opts) {
      var app = application;
      app.init(opts);
      self.app = app;
      return app;
    };
    

    pomelo/lib/application.js

    /**
     * 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'));
    };
    

    pomelo/lib/application.js

    /**
     * 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();
    };
    

    utils.argsInfo(process.argv); 获取系统启动參数,我们最好还是看看究竟有哪些參数支持 

    启动game-server服务器:>pomelo start [development | production] [--daemon]


    依据args參数设定application的工作环境是development或production

    /**
     * Setup enviroment.
     * @api private
     */
    Application.setupEnv = function(args) {
      this.set('env', args.env || process.env.NODE_ENV || 'development', true);
    };

    载入服务器信息,而且保存在__serverMap___内存下

    /**
     * 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);
    };

    server.json

    {
        "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);
    };


    master.json
    {
        "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
        }
    
    }

    依据进程读取配置好的參数,配置server。

    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');
      }
    };

    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
    }



  • 相关阅读:
    eclipse安装WTP部署WEB项目
    BZOJ3302: [Shoi2005]树的双中心
    BZOJ2059: [Usaco2010 Nov]Buying Feed 购买饲料
    BZOJ1986: [USACO2004 Dec] Dividing the Path 划区灌溉
    BZOJ3126: [Usaco2013 Open]Photo
    51nod1486 大大走格子
    BZOJ1698: [Usaco2007 Feb]Lilypad Pond 荷叶池塘
    BZOJ2590: [Usaco2012 Feb]Cow Coupons
    BZOJ1739: [Usaco2005 mar]Space Elevator 太空电梯
    BZOJ2501: [usaco2010 Oct]Soda Machine
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/3961109.html
Copyright © 2011-2022 走看看