protocol buffer的service接口生成问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了protocol buffer的service接口生成问题相关的知识,希望对你有一定的参考价值。
protocol buffer的proto文件定义的service编译后没有生成相应的服务接口,为什么?
参考技术A 什么是protocol bufferProtocolBuffer是用于结构化数据串行化的灵活、高效、自动的方法,有如XML,不过它更小、更快、也更简单。你可以定义自己的数据结构,然后使用代码生成器生成的代码来读写这个数据结构。你甚至可以在无需重新部署程序的情况下更新数据结构。
1.2 他们如何工作
你首先需要在一个 .proto 文件中定义你需要做串行化的数据结构信息。每个ProtocolBuffer信息是一小段逻辑记录,包含一系列的键值对。这里有个非常简单的 .proto 文件定义了个人信息:
message Person
required string name=1;
required int32 id=2;
optional string email=3;
enum PhoneType
MOBILE=0;
HOME=1;
WORK=2;
message PhoneNumber
required string number=1;
optional PhoneType type=2 [default=HOME];
repeated PhoneNumber phone=4;
有如你所见,消息格式很简单,每个消息类型拥有一个或多个特定的数字字段,每个字段拥有一个名字和一个值类型。值类型可以是数字(整数或浮点)、布尔型、字符串、原始字节或者其他ProtocolBuffer类型,还允许数据结构的分级。你可以指定可选字段,必选字段和重复字段。你可以在( gle.com/apis/protocolbuffers/docs/proto.html )找到更多关于如何编写 .proto 文件的信息。
一旦你定义了自己的报文格式(message),你就可以运行ProtocolBuffer编译器,将你的 .proto 文件编译成特定语言的类。这些类提供了简单的方法访问每个字段(像是 query() 和 set_query() ),像是访问类的方法一样将结构串行化或反串行化。例如你可以选择C++语言,运行编译如上的协议文件生成类叫做 Person 。随后你就可以在应用中使用这个类来串行化的读取报文信息。你可以这么写代码:
Person person;
person.set_name("John Doe");
person.set_id(1234);
person.set_email("jdoe@example.com");
fstream.output("myfile",ios::out | ios::binary);
person.SerializeToOstream(&output);
然后,你可以读取报文中的数据:
fstream input("myfile",ios::in | ios:binary);
Person person;
person.ParseFromIstream(&input);
cout << "Name: " << person.name() << endl;
cout << "E-mail: " << person.email() << endl;
你可以在不影响向后兼容的情况下随意给数据结构增加字段,旧有的数据会忽略新的字段。所以如果使用ProtocolBuffer作为通信协议,你可以无须担心破坏现有代码的情况下扩展协议。
你可以在API参考( oogle.com/apis/protocolbuffers/docs/reference/overview.html )中找到完整的参考,而关于ProtocolBuffer的报文格式编码则可以在( .google.com/apis/protocolbuffers/docs/encoding.html )中找到。
1.3 为什么不用XML?
ProtocolBuffer拥有多项比XML更高级的串行化结构数据的特性,ProtocolBuffer:
更简单
小3-10倍
快20-100倍
更少的歧义
可以方便的生成数据存取类
例如,让我们看看如何在XML中建模Person的name和email字段:
<person>
<name>John Doe</name>
<email>jdoe@example.com</email>
</person>
对应的ProtocolBuffer报文则如下:
#ProtocolBuffer的文本表示
#这不是正常时使用的二进制数据
person
name: "John Doe"
email: "jdoe@example.com"
当这个报文编码到ProtocolBuffer的二进制格式( .google.com/apis/protocolbuffers/docs/encoding.html )时(上面的文本仅用于调试和编辑),它只需要28字节和100-200ns的解析时间。而XML的版本需要69字节(除去空白)和 5000-10000ns的解析时间。
当然,操作ProtocolBuffer也很简单:
cout << "Name: " << person.name() << endl;
cout << "E-mail: " << person.email() << endl;
而XML的你需要:
cout << "Name: "
<< person.getElementsByTagName("name")->item(0)->innerText()
<< endl;
cout << "E-mail: "
<< person.getElementsByTagName("email")->item(0)->innerText()
<< end;
当然,ProtocolBuffer并不是在任何时候都比XML更合适,例如ProtocolBuffer无法对一个基于标记文本的文档建模,因为你根本没法方便的在文本中插入结构。另外,XML是便于人类阅读和编辑的,而ProtocolBuffer则不是。还有XML是自解释的,而 ProtocolBuffer仅在你拥有报文格式定义的 .proto 文件时才有意义。
1.4 听起来像是为我的解决方案,如何开始?
下 er编译器,用于生成你需要的IO类。构建和安装你的编译器,跟随README的指令就可以做到。
一旦你安装好了,就可以跟着编程指导( ogle.com/apis/protocolbuffers/docs/tutorials.html )来选择语言-随后就是使用ProtocolBuffer创建一个简单的应用了。
1.5 一点历史
ProtocolBuffer最初是在Google开发的,用以解决索引服务器的请求、响应协议。在使用ProtocolBuffer之前,有一种格式用以处理请求和响应数据的编码和解码,并且支持多种版本的协议。而这最终导致了丑陋的代码,有如:
if (version==3)
...
else if (version>4)
if (version==5)
...
...
通信协议因此变得越来越复杂,因为开发者必须确保,发出请求的人和接受请求的人必须同时兼容,并且在一方开始使用新协议时,另外一方也要可以接受。
ProtocolBuffer设计用于解决这一类问题:
很方便引入新字段,而中间服务器可以忽略这些字段,直接传递过去而无需理解所有的字段。
格式可以自描述,并且可以在多种语言中使用(C++、Java等)
然而用户仍然需要手写解析代码。
随着系统的演化,他需要一些其他的功能:
自动生成编码和解码代码,而无需自己编写解析器。
除了用于简短的RPC(Remote Procedure Call)请求,人们使用ProtocolBuffer来做数据存储格式(例如BitTable)。
RPC服务器接口可以作为 .proto 文件来描述,而通过ProtocolBuffer的编译器生成存根(stub)类供用户实现服务器接口。
ProtocolBuffer现在已经是Google的混合语言数据标准了,现在已经正在使用的有超过48,162种报文格式定义和超过 12,183个 .proto 文件。他们用于RPC系统和持续数据存储系统。
2 语言指导
本指导描述了如何使用ProtocolBuffer语言来定义结构化数据类型,包括 .proto 文件的语法和如何生成存取类。
这是一份指导手册,一步步的例子使用文档中的多种功能,查看入门指导( m/apis/protocolbuffers/docs/tutorials.html )选择你的语言。
2.1 定义一个消息类型
@waiting …
2.2 值类型
@waiting …
2.3 可选字段与缺省值
@waiting …
2.4 枚举
@waiting …
2.5 使用其他消息类型
@waiting …
2.6 嵌套类型
@waiting …
2.7 更新一个数据类型
@waiting …
2.8 扩展
@waiting …
2.9 包
@waiting …
2.10 定义服务
@waiting …
2.11 选项
@waiting …
2.12 生成你的类
@waiting …
3 代码风格指导
本文档提供了 .proto 文件的代码风格指导。按照惯例,你将会,你将会生成一些便于阅读和一致的ProtocolBuffer定义文件。
3.1 消息与字段名
使用骆驼风格的大小写命名,即单词首字母大写,来做消息名。使用GNU的全部小写,使用下划线分隔的方式定义字段名:
message SongServerRequest
required string song_name=1;
使用这种命名方式得到的名字如下:
C++:
const string& song_name() ...
void set_song_name(const string& x) ...
Java:
public String getSongName() ...
public Builder setSongName(String v) ...
3.2 枚举
使用骆驼风格做枚举名,而用全部大写做值的名字:
enum Foo
FIRST_VALUE=1;
SECOND_VALUE=2;
每个枚举值最后以分号结尾,而不是逗号。
3.3 服务
如果你的 .proto 文件定义了RPC服务,你可以使用骆驼风格:
service FooService
rpc GetSomething(FooRequest) returns (FooResponse);
4 编码
本文档描述了ProtocolBuffer的串行化二进制数据格式定义。你如果仅仅是在应用中使用ProtocolBuffer,并不需要知道这些,但是这些会对你定义高效的格式有所帮助。
4.1 一个简单的消息
@waiting …
4.2 基于128的Varints
@waiting …
4.3 消息结构
@waiting …
4.4 更多的值类型
@waiting …
4.5 内嵌消息
@waiting …
4.6 可选的和重复的元素
@waiting …
4.7 字段顺序
@waiting …
5 ProtocolBuffer基础:C++
@waiting …
6 ProtocolBuffer基础:Java
@waiting …
7
protobuf(Protocol Buffers).proto文件中的IDL(Interface Definition Language 接口定义语言)是什么?
文章目录
在 Google 的 Protocol Buffers 中,.proto 文件使用的语言就是接口定义语言(IDL),它定义了要使用的数据类型、消息结构、服务等。然后可以使用特定的编译器将 .proto 文件转换为各种编程语言的源代码,以便开发人员在各种语言中使用 Protocol Buffers。
在 “.proto” 文件中使用的 “IDL” 是 “Interface Definition Language” 的缩写。它是一种用于描述不同进程或模块之间交互接口的语言。通过编写接口定义语言,可以定义如何通过不同的进程或模块进行通信,并定义如何序列化和反序列化数据。
.proto 文件介绍
.proto 文件是 Google Protocol Buffers 的核心文件,用于定义不同进程或模块之间的数据通信协议。它描述了如何序列化和反序列化结构化数据,以便不同的进程或模块可以相互交换信息。可以将 .proto 文件看作是接口定义语言(IDL),用于定义要在进程之间传递的消息格式和服务接口。
.proto 文件中定义了消息类型、字段名称和数据类型等信息,这些信息可以用于在不同编程语言之间定义和生成可互操作的数据结构。通过使用 Protocol Buffers,开发人员可以使用.proto 文件定义结构化数据,然后使用不同的编程语言生成代码以读写这些数据。这意味着开发人员可以使用不同的编程语言开发不同的应用程序,但它们仍然可以相互交换信息,因为它们都遵循相同的数据格式和协议。
因此,.proto 文件对于开发分布式系统或跨语言应用程序非常有用。通过使用.proto 文件,开发人员可以定义消息格式和服务接口,然后使用相应的编译器生成可用于不同编程语言的代码。这样就可以轻松地构建跨平台和跨语言的应用程序。
以上是关于protocol buffer的service接口生成问题的主要内容,如果未能解决你的问题,请参考以下文章
protobuf(Protocol Buffers).proto文件中的IDL(Interface Definition Language 接口定义语言)是什么?