随着Google的Protobuf3的发布,Google终于开发了一个可以给JavaScript使用的库。之前大家如果在node端使用了Protobuf应该用的是protobufjs这个库,但是既然Google官方支持了JavaScript,那么我们还是要去尝试一下的。
下面就开始介绍如何在node端使用google-protobuf,在解析生成proto数据的同时,我们还支持一个功能:可以根据客户端请求的后缀去判断返回给客户端的数据格式(json或protobuf)。举个例子,如果客户端请求的url是http://127.0.0.1:9999/user.json,我们给他返回的就是json数据;如果客户端请求的url是http://127.0.0.1:9999/user.pb,我们给他返回的就是proto数据。下面开始详细的讲解:
关于Protobuf3如何定义数据结构的,就不详细讲解了,贴上demo中的数据结构:
body.proto:主要用来定义请求的数据结构,其中引用了define.proto:
syntax = "proto3";
import "define.proto";
message MatchStockResp {
ErrorCode errorCode = 1;
repeated MatchStock stock = 2;
}
message MatchStock {
string stockLabel = 1;
string stockName = 2;
}
syntax = "proto3";
enum ErrorCode {
DEFAULT = 0;
SUCCESS = 1;
FAIL = 2;
FORM_INVALID = 3;
}
下载protoc.exe,用于编译.proto文件。编译代码如下:
protoc --js_out=import_style=commonjs,binary:. body.proto define.proto
编译成功后,会生成body_pb.js和define_pb.js两个文件,将其考入到Node的项目中,便于之后的引用。
/**
* Created by wyk on 17/3/27.
*/
var bodyProto = require("../../proto/body_pb");
var defineProto = require("../../proto/define_pb");
module.exports = {
bodyProto: bodyProto,
defineProto: defineProto
};
var bodyProto = require('../server/utils/proto-helper').bodyProto;
var defineProto = require('../server/utils/proto-helper').defineProto;
router.post('/matchStock.*', function (req, res, next) {
var formMatchStr = req.body.matchStr;
var formMatchCount = req.body.matchCount;
var matchStockResp = new bodyProto.MatchStockResp();
var matchStockList = stockUtils.matchStock(formMatchStr, formMatchCount);
for (var i in matchStockList) {
var matchStock = new bodyProto.MatchStock();
matchStock.setStocklabel(matchStockList[i].label);
matchStock.setStockname(matchStockList[i].name);
matchStockResp.addStock(matchStock)
}
matchStockResp.setErrorcode(defineProto.ErrorCode.SUCCESS);
res.send(commonUtils.responseByUrl(matchStockResp, req.url));
});
var responseByUrl = function (resp, url) {
var lastIndex = url.lastIndexOf('.');
if(lastIndex > -1) {
var suffix = url.substr(lastIndex + 1);
if (suffix == 'pb') {
return resp.serializeBinary();
} else {
return resp.toObject();
}
} else {
return resp.toObject();
}
};
resp.serializeBinary()方法会将我们的对象序列化;resp.toObject()会将我们的proto对象转换为普通的对象。
2017.4.10添加
附上生成proto的java文件的代码:
第一步需要在proto文件的头部(‘syntax = "proto3";’的下一行)添加生成proto的java文件的包名:package com.qn.gpcloud.proto;
第二步编写bat文件,编译proto文件:
protoc -I=. --java_out=. *.proto