pomelo源码分析(六)

Server.prototype.start = function(cb) {  
    registerDefaultModules(this.app);   //注册默认模块  
    loadModules(this.app, this.masterConsole); //执行模块  
  
    var self = this;  
    this.masterConsole.start(function(err) {  
        if(err) {  
            cb(err);  
            return;  
        }  
        starter.runServers(self.app);  
        cb();  
    });  
      
    this.masterConsole.on('register', function(record) {  
        logger.debug('[master] new register connection: %j, %j', record.id, record.type);  
        self.registered[record.id] = record;  
        if(checkRegistered(self)) {  
            logger.info('[master] all servers have started and notify after start now...');  
            self.masterConsole.agent.notifyAll(AfterStart.moduleId);  
        }  
    });  
  
    this.masterConsole.on('disconnect', function(id, type, reason) {  
        crashLogger.info(util.format('[%s],[%s],[%s],[%s]', type, id, Date.now(), reason || 'disconnect'));  
    });  
};  

接上一章

	this.masterConsole.on('register', function(record) {
		logger.debug('[master] new register connection: %j, %j', record.id, record.type);
		self.registered[record.id] = record;
		if(checkRegistered(self)) {
			logger.info('[master] all servers have started and notify after start now...');
			self.masterConsole.agent.notifyAll(AfterStart.moduleId);
		}
	});

	this.masterConsole.on('disconnect', function(id, type, reason) {
		crashLogger.info(util.format('[%s],[%s],[%s],[%s]', type, id, Date.now(), reason || 'disconnect'));
	});

通过masterConsole,调用consoleService,consoleService调用masterAgent监听register事件,监听的具体函数如下

/**
 * master listen to a port and handle register and request
 *
 * @param {String} port
 * @api public
 */
MasterAgent.prototype.listen = function(port) {
	if(this.state > ST_INITED) {
		logger.error('master agent has started or closed.');
		return;
	}
	this.state = ST_STARTED;
	this.server = sio.listen(port); //io.socket 监听port
	this.server.set('log level', 0);
	
	var self = this;
	this.server.server.on('error', function(err) {
		self.emit('error', err);  //对MasterAgent 发送事件信息
	});

	this.server.sockets.on('connection', function(socket) {
		var id, type, registered;

		socket.on('register', function(msg) {
			// register a new connection
			if(msg && msg.type) {
				if(msg.type === 'client') {
					// client connection not join the map
					if(!msg.id) {
						// client should has a client id
						return;
					}
					if(self.clients[msg.id]) {
						socket.emit('register', {code: protocol.PRO_FAIL, msg: 'id has been registered. id:' + msg.id});
						return;
					}
					addConnection(self, msg.id, msg.type, msg.pid, socket);
					id = msg.id;
					type = msg.type;
					registered = true;
					socket.emit('register', {code: protocol.PRO_OK, msg: 'ok'});
					return;
				}

				if(msg.id) {
					// if is a normal server
					if(self.idMap[msg.id]) {
						socket.emit('register', {code: protocol.PRO_FAIL, msg: 'id has been registered. id:' + msg.id});
						return;
					}
					var record = addConnection(self, msg.id, msg.type, msg.pid, socket);
					id = msg.id;
					type = msg.type;
					registered = true;
					socket.emit('register', {code: protocol.PRO_OK, msg: 'ok'});
					self.emit('register', record); 
				}
			}
		});		// end of on 'register'

		// message from monitor
		socket.on('monitor', function(msg) {
			if(!registered) {
				// not register yet, ignore any message
				return;
			}

			if(type === TYPE_CLIENT) {
				logger.error('invalid message to monitor, but current connect type is client.');
				return;
			}

			msg = protocol.parse(msg);
			if(msg.respId) {
				// a response from monitor
				var cb = self.callbacks[msg.respId];
				if(!cb) {
					logger.warn('unknown resp id:' + msg.respId);
					return;
				}
				delete self.callbacks[msg.respId];
				utils.invokeCallback(cb, msg.error, msg.body);
				return;
			}

			// a request or a notify from monitor
			self.consoleService.execute(msg.moduleId, 'masterHandler', msg.body, function(err, res) {
				if(protocol.isRequest(msg)) {
					var resp = protocol.composeResponse(msg, err, res);
					if(resp) {
						socket.emit('monitor', resp);
					}
				} else {
					//notify should not have a callback
					logger.warn('notify should not have a callback.');
				}
			});
		});		// end of on 'monitor'

		// message from client
		socket.on('client', function(msg) {
			if(!registered) {
				// not register yet, ignore any message
				return;
			}
			if(type !== TYPE_CLIENT) {
				logger.error('invalid message to client, but current connect type is ' + type);
				return;
			}
			msg = protocol.parse(msg);
			// a request or a notify from client 
			// and client should not have any response to master for master would not request anything from client
			self.consoleService.execute(msg.moduleId, 'clientHandler', msg.body, function(err, res) {
				if(protocol.isRequest(msg)) {
					var resp = protocol.composeResponse(msg, err, res);
					if(resp) {
						socket.emit('client', resp);
					}
				} else {
					//notify should not have a callback
					logger.warn('notify should not have a callback.');
				}
			});
		});		// end of on 'client'

		socket.on('disconnect', function() {
			removeConnection(self, id, type);
			self.emit('disconnect', id, type);
		});

		socket.on('error', function(err) {
			self.emit('error', id, type, err);
		});
	});		// end of on 'connection'
};		// end of listen

masterAgent 和 monitorAgent主要任务就是负责监听端口传入的各种事件,下图是截取http://golanger.cn的图,图里面画对次过程描述得非常清晰


master 捕捉 'register‘事件,等待MasterAgent发出'register’事件信号的时候,执行以下代码

    this.masterConsole.on('register', function(record) {  
        logger.debug('[master] new register connection: %j, %j', record.id, record.type);  
        self.registered[record.id] = record;  
        if(checkRegistered(self)) {  
            logger.info('[master] all servers have started and notify after start now...');  
            self.masterConsole.agent.notifyAll(AfterStart.moduleId);  
        }  
    });  

执行 self.masterConsole.agent.notifyAll(AfterStart.moduleId);

通知所有模块都执行AftersStart,通知所有模块都执行afterstart,到这里为止,pomelo的启动流程基本结束

我们看看官方是怎么定义这一些列的启动过程


组件可以根据需要,提供不同的生命周期接口,pomelo框架会在生命周期的各个阶段触发相应的回调。组件的生命周期接口类型如下:

  • start(cb) 服务器启动回调。在当前服务器启动过程中,会按注册顺序触发各组件的这个接口。组件启动完毕后,需要调用cb函数通知框架执行后续流程。
  • afterStart(cb) 服务器启动完毕回调。当pomelo管理下的所有服务器进程都启动完成后会触发这个接口。一些需要等待全局就绪的工作可以放到这里来完成。
  • stop(force, cb) 服务器关闭回调。在服务器关闭期间,会根据注册顺序的逆序来触发这个回调接口,主要用来通知各个组件保存各自的数据和释放资源。force表示是否要强制关闭。操作完毕后,同样需要调用cb函数来继续后续流程。

最后,截取我的启动日志作为文章的结尾

"C:\Program Files\nodejs\node.exe" chatofpomelo\game-server\app.js
[2013-03-23 11:47:43.609] [INFO] \chatofpomelo\game-server\node_modules\pomelo\lib\application.js - app.init invoked   #启动mater 第一个服务器
[2013-03-23 11:47:43.982] [INFO] \chatofpomelo\game-server\node_modules\pomelo\lib\application.js - application inited: "master-server-1"
[2013-03-23 11:47:45.075] [INFO] console - info: 'socket.io started'
[2013-03-23 11:47:45.076] [INFO] \chatofpomelo\game-server\node_modules\pomelo\lib\master\starter.js - Executing cd #通过mater里面,runServer命令启动采用cmd命令的方式启动多个相关服务器组
 D:\src\pomelo\chatofpomelo\game-server && node  D:\src\pomelo\chatofpomelo\game-server\app.js env=development serverType=connector serverId=connector-server-1 locally
[2013-03-23 11:47:45.221] [INFO] \chatofpomelo\game-server\node_modules\pomelo\lib\master\starter.js - Executing cd D:\src\pomelo\chatofpomelo\game-server && node  D:\src\pomelo\chatofpomelo\game-server\app.js env=development serverType=connector serverId=connector-server-2 locally
[2013-03-23 11:47:45.239] [INFO] \chatofpomelo\game-server\node_modules\pomelo\lib\master\starter.js - Executing cd D:\src\pomelo\chatofpomelo\game-server && node  D:\src\pomelo\chatofpomelo\game-server\app.js env=development serverType=connector serverId=connector-server-3 locally
[2013-03-23 11:47:45.397] [INFO] \chatofpomelo\game-server\node_modules\pomelo\lib\master\starter.js - Executing cd D:\src\pomelo\chatofpomelo\game-server && node  D:\src\pomelo\chatofpomelo\game-server\app.js env=development serverType=chat serverId=chat-server-1 locally
[2013-03-23 11:47:45.468] [INFO] \chatofpomelo\game-server\node_modules\pomelo\lib\master\starter.js - Executing cd D:\src\pomelo\chatofpomelo\game-server && node  D:\src\pomelo\chatofpomelo\game-server\app.js env=development serverType=chat serverId=chat-server-2 locally
[2013-03-23 11:47:45.552] [INFO] \chatofpomelo\game-server\node_modules\pomelo\lib\master\starter.js - Executing cd D:\src\pomelo\chatofpomelo\game-server && node  D:\src\pomelo\chatofpomelo\game-server\app.js env=development serverType=chat serverId=chat-server-3 locally
[2013-03-23 11:47:45.647] [INFO] \chatofpomelo\game-server\node_modules\pomelo\lib\master\starter.js - Executing cd D:\src\pomelo\chatofpomelo\game-server && node  D:\src\pomelo\chatofpomelo\game-server\app.js env=development serverType=gate serverId=gate-server-1 locally
[2013-03-23 11:47:45.750] [INFO] \chatofpomelo\game-server\node_modules\pomelo\node_modules\pomelo-admin\lib\consoleService.js - try to connect master: "master", "127.0.0.1", 3005
[2013-03-23 11:47:45.970] [INFO] console - [2013-03-23 11:47:45.606] [INFO] \node_modules\pomelo\lib\application.js - app.init invoked #开始执行初始化对应的服务器


[2013-03-23 11:47:45.970] [INFO] console - [2013-03-23 11:47:45.895] [INFO] \node_modules\pomelo\lib\application.js - app.init invoked 


[2013-03-23 11:47:46.791] [INFO] console - [2013-03-23 11:47:45.980] [INFO] \node_modules\pomelo\lib\application.js - app.init invoked


[2013-03-23 11:47:46.791] [INFO] console - [2013-03-23 11:47:46.078] [INFO] \node_modules\pomelo\lib\application.js - app.init invoked


[2013-03-23 11:47:46.792] [INFO] console - [2013-03-23 11:47:46.139] [INFO] \node_modules\pomelo\lib\application.js - app.init invoked


[2013-03-23 11:47:46.792] [INFO] console - [2013-03-23 11:47:46.294] [INFO] \node_modules\pomelo\lib\application.js - app.init invoked


[2013-03-23 11:47:46.792] [INFO] console - [2013-03-23 11:47:46.368] [INFO] \node_modules\pomelo\lib\application.js - app.init invoked


[2013-03-23 11:47:47.116] [DEBUG] \chatofpomelo\game-server\node_modules\pomelo\lib\master\master.js - [master] new register connection: "master-server-1", "master"
[2013-03-23 11:47:47.806] [INFO] console - [2013-03-23 11:47:46.482] [INFO] \node_modules\pomelo\lib\application.js - application inited: "gate-server-1" #初始化成功信息


[2013-03-23 11:47:47.829] [INFO] console - [2013-03-23 11:47:46.274] [INFO] \node_modules\pomelo\lib\application.js - application inited: "chat-server-2"


[2013-03-23 11:47:47.840] [INFO] console - [2013-03-23 11:47:46.225] [INFO] \node_modules\pomelo\lib\application.js - application inited: "chat-server-1"


[2013-03-23 11:47:47.840] [INFO] console - [2013-03-23 11:47:46.074] [INFO] \node_modules\pomelo\lib\application.js - application inited: "connector-server-3"


[2013-03-23 11:47:47.873] [INFO] console - [2013-03-23 11:47:45.678] [INFO] \node_modules\pomelo\lib\application.js - application inited: "connector-server-1"


[2013-03-23 11:47:47.875] [INFO] console - [2013-03-23 11:47:46.420] [INFO] \node_modules\pomelo\lib\application.js - application inited: "chat-server-3"


[2013-03-23 11:47:47.913] [INFO] console - [2013-03-23 11:47:45.994] [INFO] \node_modules\pomelo\lib\application.js - application inited: "connector-server-2"


[2013-03-23 11:47:47.914] [INFO] console - [2013-03-23 11:47:47.911] [INFO] console - info: 'socket.io started' #开始对刚初始化成功的服务器进行端口监听


[2013-03-23 11:47:48.013] [INFO] console - [2013-03-23 11:47:47.832] [INFO] console - info: 'socket.io started'


[2013-03-23 11:47:48.035] [INFO] console - [2013-03-23 11:47:47.947] [INFO] \node_modules\pomelo\node_modules\pomelo-admin\lib\consoleService.js - try to connect master: "gate", "127.0.0.1", 3005  #monitor监听端口


[2013-03-23 11:47:48.035] [INFO] console - [2013-03-23 11:47:47.826] [INFO] console - info: 'socket.io started'


[2013-03-23 11:47:48.043] [INFO] console - [2013-03-23 11:47:47.831] [INFO] console - info: 'socket.io started'


[2013-03-23 11:47:48.046] [INFO] console - [2013-03-23 11:47:47.958] [INFO] \node_modules\pomelo\node_modules\pomelo-admin\lib\consoleService.js - try to connect master: "chat", "127.0.0.1", 3005


[2013-03-23 11:47:48.049] [INFO] console - [2013-03-23 11:47:47.866] [INFO] console - info: 'socket.io started'


[2013-03-23 11:47:48.051] [INFO] console - [2013-03-23 11:47:47.962] [INFO] \node_modules\pomelo\node_modules\pomelo-admin\lib\consoleService.js - try to connect master: "connector", "127.0.0.1", 3005


[2013-03-23 11:47:48.060] [INFO] console - [2013-03-23 11:47:47.873] [INFO] console - info: 'socket.io started'


[2013-03-23 11:47:48.102] [INFO] console - [2013-03-23 11:47:48.031] [INFO] \node_modules\pomelo\node_modules\pomelo-admin\lib\consoleService.js - try to connect master: "connector", "127.0.0.1", 3005


[2013-03-23 11:47:48.156] [INFO] console - [2013-03-23 11:47:47.924] [INFO] \node_modules\pomelo\node_modules\pomelo-admin\lib\consoleService.js - try to connect master: "connector", "127.0.0.1", 3005


[2013-03-23 11:47:48.187] [INFO] console - [2013-03-23 11:47:47.957] [INFO] \node_modules\pomelo\node_modules\pomelo-admin\lib\consoleService.js - try to connect master: "chat", "127.0.0.1", 3005


[2013-03-23 11:47:48.195] [DEBUG] \chatofpomelo\game-server\node_modules\pomelo\lib\master\master.js - [master] new register connection: "chat-server-2", "chat"
[2013-03-23 11:47:48.200] [DEBUG] \chatofpomelo\game-server\node_modules\pomelo\lib\master\master.js - [master] new register connection: "gate-server-1", "gate"
[2013-03-23 11:47:48.202] [DEBUG] \chatofpomelo\game-server\node_modules\pomelo\lib\master\master.js - [master] new register connection: "connector-server-3", "connector"
[2013-03-23 11:47:48.231] [DEBUG] \chatofpomelo\game-server\node_modules\pomelo\lib\master\master.js - [master] new register connection: "chat-server-1", "chat"
[2013-03-23 11:47:48.239] [INFO] console - [2013-03-23 11:47:47.969] [INFO] \node_modules\pomelo\node_modules\pomelo-admin\lib\consoleService.js - try to connect master: "chat", "127.0.0.1", 3005


[2013-03-23 11:47:48.242] [DEBUG] \chatofpomelo\game-server\node_modules\pomelo\lib\master\master.js - [master] new register connection: "chat-server-3", "chat" #完成事件监听注册
[2013-03-23 11:47:48.259] [DEBUG] \chatofpomelo\game-server\node_modules\pomelo\lib\master\master.js - [master] new register connection: "connector-server-1", "connector"
[2013-03-23 11:47:48.292] [DEBUG] \chatofpomelo\game-server\node_modules\pomelo\lib\master\master.js - [master] new register connection: "connector-server-2", "connector"
[2013-03-23 11:47:48.293] [INFO] \chatofpomelo\game-server\node_modules\pomelo\lib\master\master.js - [master] all servers have started and notify after start now...
[2013-03-23 11:47:48.295] [DEBUG] \chatofpomelo\game-server\node_modules\pomelo\lib\modules\afterStart.js - after start: "master-server-1"
[2013-03-23 11:47:48.295] [INFO] \chatofpomelo\game-server\node_modules\pomelo\lib\modules\afterStart.js - server "master-server-1" started.
[2013-03-23 11:47:48.296] [INFO] console - [2013-03-23 11:47:48.294] [DEBUG] \node_modules\pomelo\lib\modules\afterStart.js - after start: "chat-server-2"
[2013-03-23 11:47:48.295] [INFO] \node_modules\pomelo\lib\modules\afterStart.js - server "chat-server-2" started.


[2013-03-23 11:47:48.301] [INFO] console - [2013-03-23 11:47:48.297] [DEBUG] \node_modules\pomelo\lib\modules\afterStart.js - after start: "gate-server-1" #执行启动完成后的操作


[2013-03-23 11:47:48.301] [INFO] console - [2013-03-23 11:47:48.296] [DEBUG] \node_modules\pomelo\lib\modules\afterStart.js - after start: "connector-server-3"


[2013-03-23 11:47:48.312] [INFO] console - [2013-03-23 11:47:48.295] [DEBUG] \node_modules\pomelo\lib\modules\afterStart.js - after start: "chat-server-1"


[2013-03-23 11:47:48.312] [INFO] console - [2013-03-23 11:47:48.297] [DEBUG] \node_modules\pomelo\lib\modules\afterStart.js - after start: "connector-server-2"


[2013-03-23 11:47:48.312] [INFO] console - [2013-03-23 11:47:48.304] [INFO] console - info: 'socket.io started'


[2013-03-23 11:47:48.314] [INFO] console - [2013-03-23 11:47:48.305] [DEBUG] \node_modules\pomelo\lib\modules\afterStart.js - after start: "connector-server-1"


[2013-03-23 11:47:48.314] [INFO] console - [2013-03-23 11:47:48.307] [DEBUG] \node_modules\pomelo\lib\modules\afterStart.js - after start: "chat-server-3"


[2013-03-23 11:47:48.315] [INFO] console - [2013-03-23 11:47:48.296] [INFO] \node_modules\pomelo\lib\modules\afterStart.js - server "chat-server-1" started.


[2013-03-23 11:47:48.315] [INFO] console - [2013-03-23 11:47:48.304] [INFO] \node_modules\pomelo\lib\modules\afterStart.js - server "connector-server-3" started.


[2013-03-23 11:47:48.315] [INFO] console - [2013-03-23 11:47:48.307] [INFO] \node_modules\pomelo\lib\modules\afterStart.js - server "chat-server-3" started.


[2013-03-23 11:47:48.316] [INFO] console - [2013-03-23 11:47:48.306] [INFO] console - info: 'socket.io started'  #完成afterStart操作后,正式启动完毕
[2013-03-23 11:47:48.306] [INFO] \node_modules\pomelo\lib\modules\afterStart.js - server "connector-server-2" started.


[2013-03-23 11:47:48.316] [INFO] console - [2013-03-23 11:47:48.313] [INFO] console - info: 'socket.io started'
[2013-03-23 11:47:48.316] [INFO] \node_modules\pomelo\lib\modules\afterStart.js - server "connector-server-1" started.


[2013-03-23 11:47:48.339] [INFO] console - [2013-03-23 11:47:48.338] [INFO] console - info: 'socket.io started'


[2013-03-23 11:47:48.339] [INFO] console - [2013-03-23 11:47:48.339] [INFO] \node_modules\pomelo\lib\modules\afterStart.js - server "gate-server-1" started.




发布了112 篇原创文章 · 获赞 37 · 访问量 68万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章