今天在做java报表时 无意间浏览了一个block 发现了一个好东西就是Google +protobuf ,真心感觉在Socket 项目中自定义协议时,确实有些问题。第 一是效率的问题,第二是性能上存在问题。
先来介绍一下 protobuf :
protobuf是一个开源项目(官方站点在“这里 ”),而且是后台很硬的开源项目
它是鼎鼎大名的Google公司开发出来,并且在Google内部久经考验的一个东东。由此可见,它的作者绝非一般闲杂人等可比.
它的作用 :
它的功能和XML 的功能基本相似,懂XML的都知道 就是把某种数据结构的信息,以某种格式保存起来。主要用于数据存储、传输协议格式等场合。
他和XML 的区别:
你就会纳闷了,用XML 不就行了,其实不然。XML 跟它 相比还是有点不足之处的,他的缺点主要在XML的序列化和烦序列化上,在序列化上当存在大量冗余数据时,效率,开销就不是客观了,在反序列化上开销挺大的。
下面的举例 来自网络上的一位大神。
代码生成机制
除了性能好,代码生成机制是主要吸引俺的地方。为了说明这个代码生成机制,俺举个例子。
比如有个电子商务的系统(假设用C++实现),其中的模块A需要发送大量的订单信息给模块B,通讯的方式使用socket。
假设订单包括如下属性:
--------------------------------
时间:time(用整数表示)
客户id:userid(用整数表示)
交易金额:price(用浮点数表示)
交易的描述:desc(用字符串表示)
--------------------------------
如果使用protobuf实现,首先要写一个proto文件(不妨叫Order.proto),在该文件中添加一个名为"Order"的message结构,用来描述通讯协议中的结构化数据。该文件的内容大致如下:
--------------------------------
message Order
{
required int32 time = 1;
required int32 userid = 2;
required float price = 3;
optional string desc = 4;
}
--------------------------------
然后,使用protobuf内置的编译器编译 该proto。由于本例子的模块是C++,你可以通过protobuf编译器的命令行参数(看“这里 ”),让它生成C++语言的“订单包装类”。(一般来说,一个message结构会生成一个包装类)
然后你使用类似下面的代码来序列化/解析该订单包装类:
--------------------------------
// 发送方
Order order;
order.set_time(XXXX);
order.set_userid(123);
order.set_price(100.0f);
order.set_desc("a test order");
string sOrder;
order.SerailzeToString(&sOrder);
// 然后调用某种socket的通讯库把序列化之后的字符串发送出去
// ......
--------------------------------
// 接收方
string sOrder;
// 先通过网络通讯库接收到数据,存放到某字符串sOrder
// ......
Order order;
if(order.ParseFromString(sOrder)) // 解析该字符串
{
cout << "userid:" << order.userid() << endl
<< "desc:" << order.desc() << endl;
}
else
{
cerr << "parse error!" << endl;
}
--------------------------------
有了这种代码生成机制,开发人员再也不用吭哧吭哧地编写那些协议解析的代码了(干这种活是典型的吃力不讨好)。
同样在上次的项目中也可以利用它,封装自定义的协议,就可以避免编写协议解析的代码了。
最后我再补充一下,他是有Google 开发 不久交给开源社区。他的性能不必怀疑。同时他支持 C++ java Paython (官方) 不久有了各种语言的,有民间大神 开发(效率,性能 相比可想而知了)