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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章