pomelo-components
Version:
pomelo components, like protobuf, dictionary
143 lines (117 loc) • 4.23 kB
JavaScript
var logger = require('pomelo-logger').getLogger("pomelo", "ProtobufComponent");
var protobuf = require('bearcat-protobufjs');
var Constant = require('../util/constant');
var FileUtil = require('../util/fileUtil');
var Utils = require('../util/utils');
var fs = require('fs');
var ProtobufComponent = function(app, opts) {
this.app = app;
this.version = 0;
this.watchers = {};
opts = opts || {};
this.base = app.getBase();
this.env = app.get('env');
this.clientProtosPath = opts.clientProtos || '/config/' + this.env + '/clientProtos.proto';
this.serverProtosPath = opts.serverProtos || '/config/' + this.env + '/serverProtos.proto';
this.clientVersion = null;
this.serverVersion = null;
};
ProtobufComponent.prototype.name = '__decodeIO__protobuf__';
ProtobufComponent.prototype.start = function(cb) {
var app_base = this.base;
this.setProtos(Constant.TYPE_SERVER, FileUtil.pathJoin(app_base, this.serverProtosPath));
this.setProtos(Constant.TYPE_CLIENT, FileUtil.pathJoin(app_base, this.clientProtosPath));
this.encodeBuilder = protobuf.loadProtoFile(FileUtil.pathJoin(app_base, this.serverProtosPath));
this.encodeMessage = this.encodeBuilder ? this.encodeBuilder.build(Constant.PROTO_MESSAGE) : {};
this.decodeBuilder = protobuf.loadProtoFile(FileUtil.pathJoin(app_base, this.clientProtosPath));
this.decodeMessage = this.decodeBuilder ? this.decodeBuilder.build(Constant.PROTO_MESSAGE) : {};
process.nextTick(cb);
};
ProtobufComponent.prototype.check = function(type, route) {
if (type == Constant.TYPE_SERVER) {
return this.encodeMessage[route];
}
if (type == Constant.TYPE_CLIENT) {
return this.decodeMessage[route];
}
logger.error('decodeIO meet with error type of protos, type: ' + type + ' route: ' + route);
};
ProtobufComponent.prototype.encode = function(route, message) {
var encodeMessage = this.encodeMessage;
var EncodeMsg = encodeMessage[route];
if (!EncodeMsg) {
return message;
}
return new EncodeMsg(message).encode(true).toBuffer();
};
ProtobufComponent.prototype.decode = function(route, message) {
var decodeMessage = this.decodeMessage;
var DecodeMsg = decodeMessage[route];
if (!DecodeMsg) {
return message;
}
return DecodeMsg.decode(message);
}
ProtobufComponent.prototype.getProtos = function() {
return {
client: this.clientProtos,
server: this.serverProtos,
clientVersion: this.clientVersion,
serverVersion: this.serverVersion
};
}
ProtobufComponent.prototype.getVersion = function() {
return {
clientVersion: this.clientVersion,
serverVersion: this.serverVersion
}
}
ProtobufComponent.prototype.setProtos = function(type, path) {
if (!FileUtil.existsSync(path)) {
return;
}
if (type === Constant.TYPE_SERVER) {
this.serverProtos = FileUtil.readFileSync(path);
this.serverVersion = Utils.md5(this.serverProtos);
}
if (type === Constant.TYPE_CLIENT) {
this.clientProtos = FileUtil.readFileSync(path);
this.clientVersion = Utils.md5(this.clientProtos);
}
//Watch file
var watcher = fs.watch(path, this.onUpdate.bind(this, type, path));
this.addWatcher(type, watcher);
}
ProtobufComponent.prototype.addWatcher = function(type, watcher) {
if (this.watchers[type]) {
this.watchers[type].close();
}
this.watchers[type] = watcher;
}
ProtobufComponent.prototype.onUpdate = function(type, path, event) {
if (event !== 'change') {
return;
}
var self = this;
fs.readFile(path, 'utf8', function(err, data) {
if (type === Constant.TYPE_SERVER) {
self.serverProtos = data;
self.serverVersion = Utils.md5(data);
logger.debug('change proto file , type : %s, path : %s, version : %s', type, path, self.serverVersion);
} else {
self.clientProtos = data;
self.clientVersion = Utils.md5(data);
logger.debug('change proto file , type : %s, path : %s, version : %s', type, path, self.clientVersion);
}
});
}
ProtobufComponent.prototype.stop = function(force, cb) {
for (var type in this.watchers) {
this.watchers[type].close();
}
this.watchers = {};
process.nextTick(cb);
}
module.exports = function(app, opts) {
return new ProtobufComponent(app, opts);
};