From a0bc6ce0566c4075f0d91c0fe3d110274bb733e2 Mon Sep 17 00:00:00 2001 From: hefangshi Date: Wed, 25 May 2016 18:07:05 +0800 Subject: [PATCH] release 0.9.0 - support protobuf converter --- lib/config.js | 4 +- lib/ext/converter/protobufConverter.js | 95 ++++++++++++++++++++++++++ package.json | 3 +- 3 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 lib/ext/converter/protobufConverter.js diff --git a/lib/config.js b/lib/config.js index 17c9010..7e3d250 100644 --- a/lib/config.js +++ b/lib/config.js @@ -239,9 +239,9 @@ function parseContext(serviceID, options) { // } // context.protocolContext = contextCache[serviceID].protocol; context.packConverter = RalModule.modules.converter[options.pack || serviceInfo.pack]; - context.pack = context.packConverter.pack; + context.pack = context.packConverter.pack.bind(context.packConverter); context.unpackConverter = RalModule.modules.converter[options.unpack || serviceInfo.unpack]; - context.unpack = context.unpackConverter.unpack; + context.unpack = context.unpackConverter.unpack.bind(context.unpackConverter); return context; } diff --git a/lib/ext/converter/protobufConverter.js b/lib/ext/converter/protobufConverter.js new file mode 100644 index 0000000..3f17c80 --- /dev/null +++ b/lib/ext/converter/protobufConverter.js @@ -0,0 +1,95 @@ +/** + * @file node-ral + * @author hefangshi@baidu.com + * http://fis.baidu.com/ + * 2014/8/5 + */ + +'use strict'; + +var Converter = require('../../converter.js'); +var logger = require('../../logger.js')('ProtobufConverter'); +var util = require('util'); +var iconv = require('iconv-lite'); +var ProtoBuf = require("protobufjs"); + +function ProtobufConverter() { + this.globalPbBuilderCache = {}; + Converter.call(this); +} + +util.inherits(ProtobufConverter, Converter); + +ProtobufConverter.prototype.normalizeConfig = function(config) { + // save proto build for every service + var root = this.globalPbBuilderCache[config.serviceID]; + if (!root) { + var builder = ProtoBuf.newBuilder(config.pbConfig || {}); + if (config.protoPaths instanceof Array === false) { + config.protoPaths = [config.protoPaths]; + } + config.protoPaths.forEach(function(protoPath) { + ProtoBuf.loadProtoFile(protoPath, builder); + }); + root = builder.build(); + this.globalPbBuilderCache[config.serviceID] = root; + } + config.protoRoot = root; +}; + +ProtobufConverter.prototype.unpack = function(config, data) { + try { + this.normalizeConfig(config); + var root = config.protoRoot; + if (!config.decodeMessageName) { + throw new Error("decodeMessageName is needed unpack protobuf data"); + } + var MessageClass; + config.decodeMessageName.split('.').forEach(function(name) { + MessageClass = MessageClass ? MessageClass[name] : root[name]; + }); + var obj = MessageClass.decode(data); + logger.trace('unpack protobuf data succ ServiceID=' + config.serviceID); + return obj; + } catch (ex) { + logger.trace('unpack protobuf data failed ServiceID=' + config.serviceID); + throw ex; + } +}; + +ProtobufConverter.prototype.pack = function(config, data) { + data = data || {}; + var buffer; + try { + if (config.json2Pb === false) { + buffer = data.toBuffer(); + } else { + this.normalizeConfig(config); + var root = config.protoRoot; + if (!config.encodeMessageName) { + throw new Error("encodeMessageName is needed to pack protobuf data"); + } + var MessageClass; + config.encodeMessageName.split('.').forEach(function(name) { + MessageClass = MessageClass ? MessageClass[name] : root[name]; + }); + var message = new MessageClass(data); + buffer = message.toBuffer(); + } + if (!config.skipContentLength) { + config.headers = config.headers || {}; + config.headers['Content-Length'] = buffer.length; + } + } catch (ex) { + logger.trace('pack protobuf data failed data=' + data + ' ServiceID=' + config.serviceID); + throw ex; + } + logger.trace('pack protobuf data succ ServiceID=' + config.serviceID + ' length=' + buffer.length); + return buffer; +}; + +ProtobufConverter.prototype.getName = function() { + return 'protobuf'; +}; + +module.exports = ProtobufConverter; diff --git a/package.json b/package.json index f52adee..c3a42ad 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-ral", - "version": "0.8.2", + "version": "0.9.0", "description": "a rpc client for node", "main": "index.js", "scripts": { @@ -31,6 +31,7 @@ "https-proxy-agent": "1.0.0", "iconv-lite": "0.4.13", "performance-now": "0.2.0", + "protobufjs": "5.0.1", "soap": "0.8.0", "underscore": "1.6.0", "urlencode": "1.1.0",