/** * Implementation of server component. * Init and start server instance. */ var logger = require('pomelo-logger').getLogger('pomelo', __filename); var fs = require('fs'); var path = require('path'); var pathUtil = require('../util/pathUtil'); var Loader = require('pomelo-loader'); var utils = require('../util/utils'); var schedule = require('pomelo-scheduler'); var events = require('../util/events'); var Constants = require('../util/constants'); var FilterService = require('../common/service/filterService'); var HandlerService = require('../common/service/handlerService'); var ST_INITED = 0; // server inited var ST_STARTED = 1; // server started var ST_STOPED = 2; // server stoped /** * Server factory function. * * @param {Object} app current application context * @return {Object} erver instance */ module.exports.create = function(app, opts) { return new Server(app, opts); }; var Server = function (app, opts) { this.opts = opts || {}; this.app = app; this.globalFilterService = null; this.filterService = null; this.handlerService = null; this.crons = []; this.jobs = {}; this.state = ST_INITED; app.event.on(events.ADD_CRONS, this.addCrons.bind(this)); app.event.on(events.REMOVE_CRONS, this.removeCrons.bind(this)); }; var pro = Server.prototype; /** * Server lifecycle callback */ pro.start = function() { if(this.state > ST_INITED) { return; } this.globalFilterService = initFilter(true, this.app); this.filterService = initFilter(false, this.app); this.handlerService = initHandler(this.app, this.opts); this.cronHandlers = loadCronHandlers(this.app); loadCrons(this, this.app); this.state = ST_STARTED; }; pro.afterStart = function() { scheduleCrons(this, this.crons); }; /** * Stop server */ pro.stop = function() { this.state = ST_STOPED; }; /** * Global handler. * * @param {Object} msg request message * @param {Object} session session object * @param {Callback} callback function */ pro.globalHandle = function(msg, session, cb) { if(this.state !== ST_STARTED) { utils.invokeCallback(cb, new Error('server not started')); return; } var routeRecord = parseRoute(msg.route); if(!routeRecord) { utils.invokeCallback(cb, new Error('meet unknown route message %j', msg.route)); return; } var self = this; var dispatch = function(err, resp, opts) { if(err) { handleError(true, self, err, msg, session, resp, opts, function(err, resp, opts) { response(true, self, err, msg, session, resp, opts, cb); }); return; } if(self.app.getServerType() !== routeRecord.serverType) { doForward(self.app, msg, session, routeRecord, function(err, resp, opts) { response(true, self, err, msg, session, resp, opts, cb); }); } else { doHandle(self, msg, session, routeRecord, function(err, resp, opts) { response(true, self, err, msg, session, resp, opts, cb); }); } }; beforeFilter(true, self, msg, session, dispatch); }; /** * Handle request */ pro.handle = function(msg, session, cb) { if(this.state !== ST_STARTED) { cb(new Error('server not started')); return; } var routeRecord = parseRoute(msg.route); doHandle(this, msg, session, routeRecord, cb); }; /** * Add crons at runtime. * * @param {Array} crons would be added in application */ pro.addCrons = function(crons) { this.cronHandlers = loadCronHandlers(this.app); for(var i=0, l=crons.length; i