protobuf.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. var fs = require('fs');
  2. var path = require('path');
  3. var protobuf = require('pomelo-protobuf');
  4. var Constants = require('../util/constants');
  5. var crypto = require('crypto');
  6. var logger = require('pomelo-logger').getLogger('pomelo', __filename);
  7. module.exports = function(app, opts) {
  8. return new Component(app, opts);
  9. };
  10. var Component = function(app, opts) {
  11. this.app = app;
  12. opts = opts || {};
  13. this.watchers = {};
  14. this.serverProtos = {};
  15. this.clientProtos = {};
  16. this.version = "";
  17. var env = app.get(Constants.RESERVED.ENV);
  18. var originServerPath = path.join(app.getBase(), Constants.FILEPATH.SERVER_PROTOS);
  19. var presentServerPath = path.join(Constants.FILEPATH.CONFIG_DIR, env, path.basename(Constants.FILEPATH.SERVER_PROTOS));
  20. var originClientPath = path.join(app.getBase(), Constants.FILEPATH.CLIENT_PROTOS);
  21. var presentClientPath = path.join(Constants.FILEPATH.CONFIG_DIR, env, path.basename(Constants.FILEPATH.CLIENT_PROTOS));
  22. this.serverProtosPath = opts.serverProtos || (fs.existsSync(originClientPath) ? Constants.FILEPATH.SERVER_PROTOS : presentServerPath);
  23. this.clientProtosPath = opts.clientProtos || (fs.existsSync(originServerPath) ? Constants.FILEPATH.CLIENT_PROTOS : presentClientPath);
  24. this.setProtos(Constants.RESERVED.SERVER, path.join(app.getBase(), this.serverProtosPath));
  25. this.setProtos(Constants.RESERVED.CLIENT, path.join(app.getBase(), this.clientProtosPath));
  26. protobuf.init({encoderProtos:this.serverProtos, decoderProtos:this.clientProtos});
  27. };
  28. var pro = Component.prototype;
  29. pro.name = '__protobuf__';
  30. pro.encode = function(key, msg) {
  31. return protobuf.encode(key, msg);
  32. };
  33. pro.encode2Bytes = function(key, msg) {
  34. return protobuf.encode2Bytes(key, msg);
  35. };
  36. pro.decode = function(key, msg) {
  37. return protobuf.decode(key, msg);
  38. };
  39. pro.getProtos = function() {
  40. return {
  41. server : this.serverProtos,
  42. client : this.clientProtos,
  43. version : this.version
  44. };
  45. };
  46. pro.getVersion = function() {
  47. return this.version;
  48. };
  49. pro.setProtos = function(type, path) {
  50. if(!fs.existsSync(path)) {
  51. return;
  52. }
  53. if(type === Constants.RESERVED.SERVER) {
  54. this.serverProtos = protobuf.parse(require(path));
  55. }
  56. if(type === Constants.RESERVED.CLIENT) {
  57. this.clientProtos = protobuf.parse(require(path));
  58. }
  59. var protoStr = JSON.stringify(this.clientProtos) + JSON.stringify(this.serverProtos);
  60. this.version = crypto.createHash('md5').update(protoStr).digest('base64');
  61. //Watch file
  62. var watcher = fs.watch(path, this.onUpdate.bind(this, type, path));
  63. if (this.watchers[type]) {
  64. this.watchers[type].close();
  65. }
  66. this.watchers[type] = watcher;
  67. };
  68. pro.onUpdate = function(type, path, event) {
  69. if(event !== 'change') {
  70. return;
  71. }
  72. fs.readFile(path, 'utf8' ,function(err, data) {
  73. try {
  74. var protos = protobuf.parse(JSON.parse(data));
  75. if(type === Constants.RESERVED.SERVER) {
  76. protobuf.setEncoderProtos(protos);
  77. } else {
  78. protobuf.setDecoderProtos(protos);
  79. }
  80. this.version = fs.statSync(path).mtime.getTime();
  81. logger.debug('change proto file , type : %j, path : %j, version : %j', type, path, this.version);
  82. } catch(e) {
  83. logger.warn("change proto file error! path : %j", path);
  84. logger.warn(e);
  85. }
  86. });
  87. };
  88. pro.stop = function(force, cb) {
  89. for (var type in this.watchers) {
  90. this.watchers[type].close();
  91. }
  92. this.watchers = {};
  93. process.nextTick(cb);
  94. };