/** * 应用程序 * @type {Object} */ var cluster = require("cluster"); var App = module.exports = Class(function(){ return { http: null, init: function(http){ this.http = http; this.loadExtFile(); this.loadExtConfig(); }, dispatch: function(){ //路径解析 return think_require('Dispatcher')(this.http).run(); }, exec: function(){ var group = this.http.group; var controller = ''; var reg = /^[A-Za-z](\w)*$/; var self = this; //检测controller名 if (!reg.test(this.http.controller)) { controller = ''; }else{ try{ controller = A(group + "/" + this.http.controller, this.http); }catch(e){ console.log(e); } } if (!controller) { var event = C('empty_controller_event'); if (event && E(event, true).length > 0) { E(event, this.http.controller, group, this.http); return true; }; console.log(this.http.controller + " controller not found"); return send_status(this.http.res, 404); }; var action = this.http.action; var oldAction = action; //添加action后缀 action += C('action_suffix') || ""; //检测action名 if (!reg.test(action)) { console.log('action name error'); return send_status(this.http.res, 404); }; var initReturnPromise = get_promise(controller.__initReturn); //对应的action方法存在 if (typeof controller[action] == 'function') { //方法参数自动绑定,直接从形参里拿到对应的值 if (C('url_params_bind')) { var toString = controller[action].toString(); toString = toString.replace(/((\/\/.*$)|(\/\*[\s\S]*?\*\/)|(\s))/mg, ''); var match = toString.match(/^function\s*[^\(]*\(\s*([^\)]*)\)/m)[1].split(/,/).filter(function(item){ return item; }); //匹配到形参 if (match && match.length) { var data = []; match.forEach(function(item){ var value = self.http.post[item] || self.http.get[item] || ""; data.push(value); }); return initReturnPromise.then(function(){ return self.execAction(controller, action, oldAction, data); }) } } return initReturnPromise.then(function(){ return self.execAction(controller, action, oldAction); }) }else{ //当指定的方法不存在时,调用魔术方法 //默认为__call方法 if (C('call_method') && typeof controller[C('call_method')] == 'function') { return initReturnPromise.then(function(){ return controller[C('call_method')](action); }); }; } console.log("action: " + action + " not found"); return send_status(this.http.res, 404); }, /** * 执行一个action, 支持before和after的统一操作 * 不对每个action都增加一个before和after,而是使用统一的策略 * 默认before和after调用名__before和__after * @param {[type]} controller [description] * @param {[type]} action [description] * @param {[type]} oldAction [description] * @param {[type]} data [description] * @return {[type]} [description] */ execAction: function(controller, action, oldAction, data){ //before action var before = C('before_action_name'); if (before && typeof controller[before] == 'function') { controller[before].call(controller, oldAction, action); }; var ret = null; //绑定方法参数 if (data) { ret = controller[action].apply(controller, data); }else{ ret = controller[action](); } //after action var after = C('after_action_name'); if (after && typeof controller[after] == 'function') { controller[after].call(controller, oldAction, action); }; return ret; }, //加载自定义外部文件 loadExtFile: function(){ var files = C('load_ext_file'); if (files) { if (is_string(files)) { files = files.split(','); }; files.forEach(function(file){ file = COMMONT_PATH + "/" + file + ".js"; if (is_file(file)) { require(file); }; }) }; }, //加载额外的配置 loadExtConfig: function(){ var files = C('load_ext_config'); if (files) { if (is_string(files)) { files = files.split(","); }; files.forEach(function(file){ file = CONF_PATH + "/" + file + ".js"; if (is_file(file)) { C(require(file)); }; }) }; } } }); /** * run * @return {[type]} [description] */ module.exports.run = function(){ //命令行调用 if (CLI_REQUEST) { var http = think_require("Http").cli(CLI_REQUEST); return App.listener(http); }; var clusterNums = C('use_cluster'); //不使用cluster if (clusterNums === false) { return App.createServer(); } if (clusterNums === 0 || clusterNums === true) { clusterNums = require('os').cpus().length; }; var cluster = require('cluster'); if (cluster.isMaster) { for (var i = 0; i < clusterNums; i++) { cluster.fork(); } cluster.on('exit', function(worker, code, signal) { console.log('worker ' + worker.process.pid + ' died'); process.nextTick(function(){ cluster.fork(); }); }); }else { App.createServer(); } } /** * 创建服务 * @return {[type]} [description] */ module.exports.createServer = function(){ var server = require("http").createServer(function (req, res) { think_require("Http")(req, res).run(App.listener); }); var params = [C('port')]; //禁止外网直接通过IP访问 if (C('deny_remote_access_by_ip')) { params.push("127.0.0.1"); }; server.listen.apply(server, params); }; /** * 监听回调函数 * @param {[type]} http [description] * @return {[type]} [description] */ module.exports.listener = function(http){ //自动发送thinkjs和版本的header http.setHeader("X-Powered-By", "thinkjs-" + THINK_VERSION); //初始化Session if (C('session_auto_start')) { think_require('Session').start(http); }; var instance = App(http); return tag ('app_init', http).then(function(){ return instance.dispatch(); }).then(function(){ return tag('app_begin', http); }).then(function(){ return tag('action_init', http); }).then(function(){ return instance.exec(); }).then(function(){ return tag('app_end', http); }) }