UNPKG

newbeely-nodejs

Version:

简单易用的轻量级nodejs服务框架. 框架简单到只有组件逻辑,不同的组件提供不同的服务,使用外部的配置文件(只有一个配置文件)方便的组合成一个完整的服务框架. 整个服务使用bearcat(网易开源的nodejs面向切面编程的轻量级框架(AOP))管理,极大的解耦组件间的耦合.(关于代码热更新后续开放).

128 lines (113 loc) 3.48 kB
var Net = require('net'); var Tls = require('tls'); var EventEmitter = require('events').EventEmitter; var Util = require('util'); var Logger = require('pomelo-logger').getLogger('newbbely', 'tcpComponent'); var Bearcat = require('bearcat'); var Path = require('path'); var FS = require('fs'); /** * * @class TcpComponent * @param sid * @param opts * @constructor */ function TcpComponent(sid, opts) { EventEmitter.call(this); this.sid = sid; this.opts = opts; this.accepter = null; this.app = null; this.connections = {}; this.methods = {}; Logger.info("TcpComponent will start at " + JSON.stringify(this.opts)); } Util.inherits(TcpComponent, EventEmitter); /** * */ TcpComponent.prototype.init = function () { this.opts["path"] = Path.join(this.app.workedir, "/app/", this.sid); try { var _this = this; var files = FS.readdirSync(Path.join(this.opts.path, "/handle")); __.each(files, function (element, index, list) { _this.methods[Path.basename(element, '.js')] = require(Path.join(self.opts.path, "/handle/", element))(); }); } catch (e) { Logger.error("load tcp handle fialed!" + e); } }; /** * */ TcpComponent.prototype.start = function () { Logger.info("TcpComponent " + this.sid + " is starting..."); if (this.opts.ssl) { this.accepter = Tls.createServer(this.opts.ssl); this.accepter.on('secureConnection', Accept.bind(null, this)); this.accepter.on('clientError', function (e, tlsSo) { Logger.warn('an ssl error occured before handshake established: ', e); tlsSo.destroy(); }); } else { this.accepter = Net.createServer(); this.accepter.on('connection', Accept.bind(null, this)); } this.accepter.on('error', this.emit.bind(this, 'error')); this.accepter.listen(this.opts.port, this.opts.host); Logger.info("TcpComponent " + this.sid + " is started!"); }; /** * */ TcpComponent.prototype.stop = function () { this.accepter.stop(); }; /** * * @param component * @param socket * @constructor */ function Accept(component, socket) { var connect = Bearcat.getBean('tcp-connection', socket, component.opts.protocol); connect.once('close', function () { delete component.connections[connect.sid]; }); connect.on('timeout', function () { Logger.debug("Connection " + connect.sid + " timeout!"); connect.kick("timeout"); }); connect.on('error', function (error) { Logger.warn('Connection has error for ' + error); }); connect.on('message', function (message) { if (!message.route) { connect.kick('format error!'); return; } var routes = message.route.split(/[.]/); routes = __.compact(routes); if (component.methods[routes[0]] && component.methods[routes[0]][routes[1]]) { component.methods[routes[0]][routes[1]](message.body, function (error, data) { connect.send(0, message.reqid, message.route, error || data, "utf8"); }); } }); component.connections[connect.sid] = component; } module.exports = { id: "tcpComponent", func: TcpComponent, init: "init", scope: "prototype", args: [ {name: "sid", "type": "String"}, {name: "opts", type: "Object"} ], "props": [ {name: "app", "ref": "application"} ] };