您的位置:首页 > Web前端

google protocol buffer的原理和使用(四)

2017-04-26 17:05 169 查看
有个电子商务的系统(如果用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;

}

--------------------------------

  有了这样的代码生成机制,开发者再也不用吭哧吭哧地编写那些协议解析的代码了(干这样的活是典型的吃力不讨好)。

  万一将来需求发生变更,要求给订单再添加一个“状态”的属性,那仅仅须要在Order.proto文件里添加一行代码。

对于发送方(模块A)。仅仅要添加一行设置状态的代码;对于接收方(模块B)仅仅要添加一行读取状态的代码。哇塞,简直太轻松了!

  另外,假设通讯两方使用不同的编程语言来实现。使用这样的机制能够有效确保两边的模块对于协议的处理是一致的。

  顺便跑题一下。

  从某种意义上讲,能够把proto文件看成是描写叙述通讯协议的规格说明书(或者叫接口规范)。这样的伎俩事实上老早就有了,搞过微软的COM编程或者接触过CORBA的同学,应该都能从中看到IDL(详解看“这里 ”)的影子。它们的思想是相通滴。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: