UNPKG

zeanium-node

Version:

Zeanium for Node.js, simple http server and custome your business.

270 lines (254 loc) 10.8 kB
/** * Created by yangyxu on 8/20/14. */ zn.define([ 'node:chokidar', 'node:fs', 'node:os', 'node:path', './Scanner', './RequestAcceptor', './controller/HttpServerController', '../../session/MemorySessionManager' ], function (chokidar, node_fs, node_os, node_path, Scanner, RequestAcceptor, HttpServerController, MemorySessionManager) { var CONFIG = { PLUGIN: 'zn.plugin.config.js', SERVER: 'zn.server.config.js', APP: 'zn.app.config.js' }; return zn.Class({ events: ['init', 'loading', 'loaded'], statics: { getContext: function (inArgs) { return new this(inArgs); } }, properties: { config: null, webPath: null, serverPath: null }, methods: { init: function (args){ var _config = args.config; this.sets(args); this.on('init', _config.onInit || zn.idle); this.on('loading', _config.onLoading || zn.idle); this.on('loaded', _config.onLoaded || zn.idle); this.__resetWatchCwd(); this.__init(); this._root = this.__getURL(_config.host, _config.port); this._sessionManager = new MemorySessionManager(_config.session); this._scanner = new Scanner(this); this._requestAcceptor = new RequestAcceptor(this); this._baseRouters = this.__registerHttpServerController(); this.__scanWebPath(); zn.SERVER_PATH = this._serverPath; zn.SERVER_URL = this._root; zn.WEB_PATH = this._webPath; }, __init: function (){ this._apps = {}; this._routers = {}; this._collections = {}; this._changedFiles = []; this._deployDelay = 0; }, __resetWatchCwd: function () { var _main = '', _config = this._config, _catalog = _config.catalog, _modules = _config.modules; if(_modules && _modules[0]){ _main = _modules[0]; } this._config.watchCwd = node_path.normalize(_catalog + _main + this._config.watchCwd); }, getRouters: function (){ return zn.extend(this._baseRouters, this._routers); }, __registerHttpServerController: function (){ var _key = HttpServerController.getMeta('controller') || ''; var _controller = new HttpServerController(this); var _member, _router, _routers = {}, _self = this; HttpServerController._methods_.forEach(function (method, index){ if(method!=='init'){ _member = HttpServerController.member(method); if(_member.meta.router!==null){ _router = _member.meta.router || _member.name; _router = node_path.normalize('/' + _key + '/' + _router); _routers[_router] = { controller: _controller, action: method, handler: _member, appContext: _self }; } } }); return _routers; }, accept: function (serverRequest, serverResponse){ serverRequest.url = node_path.normalize(serverRequest.url); this._requestAcceptor.accept(serverRequest, serverResponse); }, matchRouter: function (url){ }, registerRouters: function (routers){ return zn.extend(this._routers, routers), this; }, registerApplication: function (app){ if(!app){ return } var _deploy = app._deploy; var _app = this._apps[_deploy]; if(_app){ zn.extend(app._routers, _app._routers); } else { this._apps[_deploy] = app; } app.parentContext = this; zn.extend(this._routers, app._routers); zn.extend(this._collections, app._collections); //console.log(Object.keys(this._routers)); //app.fire('register', this); zn.info('Register Project(Application): ' + _deploy); }, __scanWebPath: function (isRedeploy){ var _config = this._config, _webPath = this._webPath, _self = this; if(node_fs.existsSync(_webPath + CONFIG.APP)){ var _queue = zn.queue(); _config.node_modules && _config.node_modules.forEach(function (name, index){ var _paths = require.resolve(name).split(name); _queue.push(function (task){ _self._scanner.scanApplication(_paths[0], name, function (app){ _self.registerApplication(app); }).then(function (){ task.done(); }); }, _self); }); _queue.push(function (task){ this._scanner.scanApplication(_webPath, '', function (app){ _self.registerApplication(app); }).then(function (){ task.done(); }); }.bind(this), _self); _queue.finally(function(){ _self.__onLoaded(_webPath); }).start(); } else { //第一次扫描系统的项目 this.__scanWebRoot(this._serverPath + zn.SLASH + 'www' + zn.SLASH, function (){ //第二次扫描用户的项目 this.__scanWebRoot(_webPath, function (){ this.__onLoaded(_webPath); }.bind(this)); }.bind(this)); /* if(isRedeploy){ this.__scanWebRoot(_webPath, function (){ this.__onLoaded(_webPath); }.bind(this)); } else { }*/ } }, __scanWebRoot: function (path, callback){ var _defer = zn.async.defer(), _self = this; this._scanner.scanWebRoot(path, function (appContext){ _self.registerApplication(appContext); }).then(function (apps){ zn.info('[ End ] Scanning Path(Application:' + apps.length + '):' + path); callback && callback(apps); _defer.resolve(apps); }, function (error){ _defer.reject(error); }); return _defer.promise; }, __watch: function (path){ if(this._watching){ return false; } var _path = node_path.join(process.cwd(), (this._config.watchCwd||'')); this._watching = true; chokidar.watch('.', { ignored: /[\/\\]\./, cwd: _path, interval: 100, binaryInterval: 300, depth: 99, persistent: true }).on('raw', function(event, path, details) { var _path = path || details.path || details.watchedPath; if(_path.substr(-3, 3)=='.js'){ if(this._changedFiles.indexOf(_path)==-1 && event!=='unknown'){ this._changedFiles.push(_path); zn.debug(event + ': ' + _path); this._deployDelay = this._config.reDeployDelay || 3000; this.__doFileChange(_path); } } }.bind(this)); zn.info('Watching: ', _path); }, __delayDeploy: function (){ if(this._interval){ clearInterval(this._interval); this._interval = null; } zn.info('Redeploying......'); this.__init(); return this.__scanWebPath(true); }, __doFileChange: function (path){ var _self = this; if(node_fs.existsSync(path)){ zn.module.unloadModule(path); } if(this._deployDelay>0){ if(!this._interval){ this._interval = setInterval(function (){ //zn.debug('Deploy delay ' + _self._deployDelay + 'ms'); if(_self._deployDelay>0){ _self._deployDelay = _self._deployDelay - 1000; }else { _self.__delayDeploy(); } }, 1000); } }else { this.__delayDeploy(); } }, __onLoaded: function(path){ if(path){ this.__watch(path); } var _interfaces = node_os.networkInterfaces(), _interface = null, _config = this._config; for(var key in _interfaces){ _interface = _interfaces[key]; _interface.forEach(function (value, index){ if(value.family == 'IPv4'){ zn.info(this.__getURL(value.address, _config.port)); } }.bind(this)); } zn.info(this._root); this.fire('loaded'); }, __getURL: function (host, port){ return (this._config.https?'https':'http') + '://' + host + ":" + port; } } }); });