ProtocolBuffer中文翻译.docx_第1页
ProtocolBuffer中文翻译.docx_第2页
ProtocolBuffer中文翻译.docx_第3页
ProtocolBuffer中文翻译.docx_第4页
ProtocolBuffer中文翻译.docx_第5页
已阅读5页,还剩32页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Protocol Buffer中文翻译1简介41.1概览41.2什么是protocol buffer41.3他们如何工作41.4为什么不用XML51.5一点历史72语言指导72.1定义一个消息类型82.1.1指定字段类型82.1.2分配标识号82.1.3指定字段规则92.1.4添加更多消息类型92.1.5添加注释102.1.6从你的.proto文件生成了什么?102.2标量数值类型102.3可选的字段和默认值112.4枚举122.5使用其他消息类型122.5.1导入定义132.6嵌套类型142.6.1Groups152.7更新一个消息类型152.8扩展152.8.1嵌套的扩展162.8.2选择可扩展的标符号172.9包(Package)182.9.1包及名称的解析182.10定义服务(Service)182.11选项(Options)202.12自定义选项222.13生成访问类243编码风格253.1消息和字段名253.2枚举253.3服务264编码264.1一个简单的消息264.2Base 128 Varints264.3消息结构274.4更多的值类型284.4.1有符号整数284.4.2非varint数字294.4.3字符串294.5嵌套的消息304.6可选和重复元素304.6.1Packed Repeated字段304.7字段顺序315Protocol Buffer Basics: Java315.1定义proto文件315.2编译Protocol Buffers文件335.3Protocol Buffer API使用335.3.1枚举和嵌套类355.3.2Builders 对Messages355.3.3标准的Message方法355.3.4解析及序列化365.3.5写入消息365.3.6读取消息385.3.7对Protocol Buffer进行扩展395.4高级用法406Techniques401 简介1.1 概览欢迎来到protocol buffer的开发者指南文档,一种语言无关、平台无关、扩展性好的用于通信协议、数据存储的结构化数据串行化方法。本文档面向希望使用protocol buffer的Java、C+或Python开发者。这个概览介绍了protocol buffer,并告诉你如何开始,你随后可以跟随编程指导( /apis/protocolbuffers/docs/tutorials.html )深入了解protocol buffer编码方式( /apis/protocolbuffers/docs/encoding.html )。API参考文档( /apis/protocolbuffers/docs/reference/overview.html )同样也是提供了这三种编程语言的版本,协议语言( /apis/protocolbuffers/docs/proto.html )和样式( /apis/protocolbuffers/docs/style.html )指导都是编写 .proto 文件。1.2 什么是protocol bufferProtocolBuffer是用于结构化数据串行化的灵活、高效、自动的方法,有如XML,不过它更小、更快、也更简单。你可以定义自己的数据结构,然后使用代码生成器生成的代码来读写这个数据结构。你甚至可以在无需重新部署程序的情况下更新数据结构。1.3 他们如何工作你首先需要在一个 .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类型,还允许数据结构的分级。你可以指定可选字段,必选字段和重复字段。你可以在( /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();fstream.output(myfile,ios:out | ios:binary);person.SerializeToOstream(&output);然后,你可以读取报文中的数据:fstream input(myfile,ios:in | ios:binary);Person person;person.ParseFromIstream(&input);cout Name: () endl;cout E-mail: person.email() endl;你可以在不影响向后兼容的情况下随意给数据结构增加字段,旧有的数据会忽略新的字段。所以如果使用ProtocolBuffer作为通信协议,你可以无须担心破坏现有代码的情况下扩展协议。你可以在API参考( /apis/protocolbuffers/docs/reference/overview.html )中找到完整的参考,而关于ProtocolBuffer的报文格式编码则可以在( /apis/protocolbuffers/docs/encoding.html )中找到。1.4 为什么不用XML如果要序列化结构化数据,比起XML,PB实在是有许多的优点可以道道 更简单 比XML小310倍 比XML快20100倍 语义定义明确 自动生成数据存取类,更容易使用假如我们要模拟一个Person,该对象包含name和email属性,如果用XML,我们定义如下: John Doe 对应的,PB如下:# Textual representation of a protocol buffer.# This is *not* the binary format used on the wire.person name: John Doe email: 请注意:这里仅是PB格式的一种直观表示,真实的PB并非这样存储,实际上,在链路中,PB数据时二进制格式的。当这段数据编码为PB二进制格式时,其实际大小大概是28bytes,编码时间为100200纳秒。如果用XML的话,即使去除空格,大小也至少为69bytes,编码时间大概需要500010,000纳秒。同样,解析这段代码,PB比XML要方便许多。用PB的话: cout Name: () endl; cout E-mail: person.email() endl;而用XML的话: cout Name: item(0)-innerText() endl; cout E-mail: item(0)-innerText() 4) if (version = 5) . .另外,这种显示格式的协议同样将新发布的协议版本也搞得非常复杂,因为开发者必须在启用新的协议之前,确认所有的服务器,包括请求的发起者以及实际处理请求者,他们都能够理解新的协议。PB即被设计来解决这些问题: 要可以非常容易的引入新字段,不需要检查数据的中间服务器 能够简单地解析数据,并且无须知道数据所有的字段就可以传输数据。 格式能够更加的自描述一些,并且可以被多用语言处理(C +, Java,Python等)至此,虽然解决了诸多问题,但用户依然需要手写他们的解析及编码代码。随着系统的发展,PB逐渐形成了许多新的特性及用法: 自动生成序列化及反序列化代码,避免手动解析 除了被用在短生命周期的RPC请求,也开始将PB作为一种方便的自描述格式去存储持久化数据。 Server RPC interfaces 开始被声明为协议文件的一部分,使用PB compiler 生成stub类,用户可以使用自己实现的服务器接口来覆盖他们。Google Protocol Buffer( 简称 Protobuf) 是 Google 公司内部的混合语言数据标准,目前已经正在使用的有超过 48,162 种报文格式定义和超过 12,183 个 .proto 文件。他们用于 RPC 系统和持续数据存储系统。2 语言指导 定义一个消息(message)类型 标量值类型 可选的(optional)字段以及默认值 枚举 使用其他消息类型 嵌套类型 更新一个消息类型 扩展 包(package) 定义服务(service) 选项(option) 生成访问类本指南描述了怎样使用protocol buffer语言来构造你的protocol buffer数据,包括.proto文件语法以及怎样生成.proto文件的数据访问类。本文是一个参考指南如果要查看如何使用本文中描述的多个特性的循序渐进的例子,请在tutorial中查找你需要的语言的教程。2.1 定义一个消息类型首先看一个非常简单的例子。假设你想定义一个“搜索请求”(search request)的消息格式,每一个搜索请求含有一个查询字符串、你感兴趣的查询结果所在的页数,以及每一页多少条查询结果。那么下面这个就是用来定义消息类型的.proto文件了:message SearchRequest required string query = 1; optional int32 page_number = 2; optional int32 result_per_page = 3;SearchRequest消息类型指定了3个字段(名/值 对),你想在消息中承载的数据分别对应于每一个字段。每个字段都有一个名字(name)和一个类型(type)。2.1.1 指定字段类型在上面的例子中,所有字段都是标量类型(scalar types):两个整型(page_number和result_per_page),一个string(query)。然而,你也可以为字段指定组合类型,包括枚举(enumerations)以及其他消息类型。2.1.2 分配标识号如你所见,在消息定义中,每一个字段都有一个独一无二的标识号(unique numbered tag)。这些标识号是用来在消息二进制格式(message binary format)中识别你的字段的。注意:1,15之内的标识号在编码的时候会占用一个字节。16,2047之内的标识号则占用2个字节。所以你应该为那些频繁出现的消息元素保留1,15之内的标识号。切记:要为将来有可能添加的、频繁出现的标识号预留一些标识号。The smallest tag number you can specify is 1, and the largest is 229- 1, or 536,870,911. You also cannot use the numbers 19000 though 19999 (FieldDescriptor:kFirstReservedNumberthroughFieldDescriptor:kLastReservedNumber), as they are reserved for the Protocol Buffers implementation - the protocol buffer compiler will complain if you use one of these reserved numbers in to.2.1.3 指定字段规则你所指定的消息字段必须是如下之一: l required:一个格式良好的消息一定要含有1个这种字段。 l optional:一个格式良好的消息可以有0个或1个这种字段(但不超过1个)。 l repeated:在一个格式良好的消息中,这种字段可以重复任意多次(包括0次)。重复的值的顺序会被保留。由于历史原因,基本数值类型的repeated的字段并没有被尽可能地高效编码。在新的代码(译者注:这里是指.proto文件的内容)中,用户应该使用特殊选项packed=true来保证更高效的编码。例如:repeated int32 samples = 4 packed=true;required是永久性的:在把一个字段标识为required的时候,你应该特别小心。如果在某些情况下你不想写入或者发送一个required的字段,那么将该字段更改为optional可能会遇到问题旧版本的读者(译者注:即读取、解析消息的一方)会认为不含该字段的消息(message)是不完整的,从而有可能会拒绝解析。在这种情况下,你应该考虑编写特别针对于应用程序的、自定义的消息校验函数。Google的一些工程师得出了一个结论:使用required弊多于利;他们更愿意使用optional和repeated而不是required。当然,这个观点并不具有普遍性。2.1.4 添加更多消息类型在一个.proto文件中可以定义多个消息类型。在定义多个相关的消息的时候,这一点特别有用例如,如果你想定义与你的SearchResponse消息类型对应的回复消息格式的话,你可以将它添加到相同的.proto文件中:message SearchRequest required string query = 1; optional int32 page_number = 2; optional int32 result_per_page = 3;message SearchResponse .2.1.5 添加注释向.proto文件添加注释,可以使用C/C+风格的双斜杠(/)语法格式。message SearchRequest required string query = 1; optional int32 page_number = 2;/ Which page number do we want? optional int32 result_per_page = 3;/ Number of results to return per page.2.1.6 从你的.proto文件生成了什么?当你对.proto文件运行protocol buffer编译器(protocol buffer compiler)的时候,编译器生成你所选择的语言的代码,这些代码可以操作你在.proto文件中定义的消息类型,包括获取、设置字段值,将你的消息序列化到一个输出流中,以及从一个输入流中解析你的消息。对C+来说,编译器为每一个.proto文件生成了一个.h文件和一个.cc文件,.proto文件中的每一个消息有一个对应的类。对Java来说,编译器为每一个消息类型生成了一个.java文件,以及一个特殊的Builder类(这个类是用来创建消息类接口的)。对Python来说,有点不一样Python编译器为.proto文件中的每个消息类型生成一个模型,其含有一个静态描述符(static descriptor,译者注:没用过Python,不清楚这样翻译正确与否),该模型与一个元类(metaclass)在运行时(runtime)被用来创建必需的Python数据访问类。你可以从每种语言的教程中找到更多使用使用API的方法。如欲查看更详细的API信息,请阅相关的文章API reference。2.2 标量数值类型一个标量消息字段可以含有一个如下的类型该表格展示了定义于.proto文件中的类型,以及与之对应的、在自动生成的访问类中定义的类型:.proto TypeNotesC+JavaPython2doubledoubledoublefloatfloatfloatfloatfloatint32使用可变长编码方式。编码负数时不够高效如果你的字段可能含有负数,那么请使用32intintint64使用可变长编码方式。编码负数时不够高效如果你的字段可能含有负数,那么请使用64longint/long3uint32使用可变长编码方式。uint32int1int/long3uint64使用可变长编码方式。uint64long1int/long3sint32使用可变长编码方式。有符号的整型值。编码时比通常的int32高效。int32intintsint64使用可变长编码方式。有符号的整型值。编码时比通常的int64高效。int64longint/long3fixed32总是4个字节。如果数值总是比总是比228大的话,这个类型会比uint32高效。uint32int1intfixed64总是8个字节。如果数值总是比总是比256大的话,这个类型会比uint64高效。uint64long1int/long3sfixed32总是4个字节。int32intintsfixed64总是8个字节。int64longint/long3boolboolbooleanbooleanstring一个字符串必须是UTF-8编码或者7-bit ASCII编码的文本。stringStringstr/unicode4bytes可能包含任意顺序的字节数据。stringByteStringstr你可以在文章Protocol Buffer Encoding中,找到更多“序列化消息时各种类型如何编码”的信息。1 在Java中,无符号32位和64位整型以它们对应的有符号类型来表示。2 In all cases, setting values to a field will perform type checking to make sure it is valid.3 64-bit or unsigned 32-bit integers are always represented as long when decoded, but can be an int if an int is given when setting the field. In all cases, the value must fit in the type represented when set. See 2.4 Python strings are represented as unicode on decode but can be str if an ASCII string is given (this is subject to change).2.3 可选的字段和默认值如上所述,消息描述中的一个元素可以被标记为“可选的”(optional)。一个格式良好的消息可以包含一个optional的元素,也可以不包含。当解析一个消息的时候,如果它不包含optional的元素,那么解析出来的对象中的对应字段就被置为默认值。默认值可以在消息描述文件中指定。例如,要为SearchRequest消息的result_per_page字段指定默认值10,可以这样做:optional int32 result_per_page = 3 default = 10;如果没有为optional的元素指定默认值,那么就会使用与特定类型相关的默认值:对string来说,默认值是空字符串。对bool来说,默认值是false。对数值类型来说,默认值是0。对枚举来说,默认值是枚举类型定义中的第一个值。2.4 枚举当你定义一个消息类型的时候,你可能想为一个字段指定某“预定义值序列”(pre-defined list of values)中的一个值。例如,假设你想为每一个SearchRequest消息添加一个corpus字段,而corpus的值可能是UNIVERSAL,WEB,IMAGES,LOCAL,NEWS,PRODUCTS或VIDEO中的一个。你可以很容易地实现这一点:通过向你的消息定义中添加一个枚举(enum)就可以了。一个enum类型的字段只能用指定的常量集(specified set of constants)中的一个值作为其值(如果你尝试指定不同的值,解析器就会把它当作一个未知的字段来对待)。在下面的例子中,我们已经添加了一个叫做Corpus的枚举(enum)它含有所有可能的值以及一个类型为Corpus的字段:message SearchRequest required string query = 1; optional int32 page_number = 2; optional int32 result_per_page = 3 default = 10; enum Corpus UNIVERSAL = 0; WEB = 1; IMAGES = 2; LOCAL = 3; NEWS = 4; PRODUCTS = 5; VIDEO = 6; optional Corpus corpus = 4 default = UNIVERSAL;枚举常量必须在32-bit整型值的范围内。因为enum值是使用可变编码方式的,对负数不够高效,因此不推荐在enum中使用负数。如上例所示,你可以在一个消息定义的内部或外部定义枚举这些枚举可以在你的.proto文件中的任何消息定义里重用。你也可以在一个消息中声明一个枚举类型,而在另一个不同的消息中使用它采用MessageType.EnumType的语法格式。当你对一个使用了枚举的.proto文件运行protocol buffer编译器的时候,生成的代码中将有一个对应的enum(对Java或C+来说),或者一个特殊的EnumDescriptor类(对Python来说),它被用来在运行时生成的类中创建一系列的整型值符号常量(symbolic constants)。关于如何在你的应用程序的消息中使用枚举的更多信息,请查看你所选择的语言的generated code guide。2.5 使用其他消息类型你可以将其他消息类型用作字段类型。例如,假设你想在每一个SearchResponse消息中包含Result消息,你可以这样做在相同的.proto文件中定义一个Result消息类型,然后在SearchResponse消息中指定一个Result类型的字段:message SearchResponse repeated Result result = 1;message Result required string url = 1; optional string title = 2; repeated string snippets = 3;2.5.1 导入定义在上面的例子中,Result消息类型与SearchResponse是定义在同一文件中的如果你要使用的消息类型已经在其他.proto文件中已经定义过了呢?你可以通过导入(importing)其他.proto文件中的定义来使用它们。要导入其他.proto文件的定义,你需要在你的文件中添加一个导入声明:import myproject/other_to;By default you can only use defintions from directly tofiles. However, sometimes you may need to move tofile to a new location. Instead of moving tofile directly and updating all the call sites in a single change, now you can put a tofile in the old location to forward all the imports to the new location using theimport publicnotion.import publicdependencies can be transitively relied upon by anyone importing the proto contaning theimport publicstatement. For example:/ to/ All definitions are moved here/ to/ This is the proto that all clients are importing.import public to;import to;/ toimport to;/ You use definitions from to and to, but not to然后,protocol编译器就会在一系列目录中查找需要被导入的文件,这些目录通过protocol编译器的命令行参数-I/import_path指定。如果不提供参数,编译器就在其调用目录下查找。2.6 嵌套类型你可以在其他消息类型中定义、使用消息类型,在下面的例子中,Result消息就定义在SearchResponse消息内:message SearchResponse message Result required string url = 1; optional string title = 2; repeated string snippets = 3; repeated Result result = 1;如果你想在它的父消息类型的外部重用这个消息类型,你需要以Parent.Type的形式使用它:message SomeOtherMessage optional SearchResponse.Result result = 1;你可以将消息嵌套任意多层:message Outer / Level 0 message MiddleAA / Level 1 message Inner / Level 2 required int64 ival = 1; optional bool booly = 2; message MiddleBB / Level 1 message Inner / Level 2 required int32 ival = 1; optional bool booly = 2; 2.6.1 Groups废弃,使用嵌套类型2.7 更新一个消息类型如果一个已有的消息无法再满足你的需求例如,你想在消息中添加一个额外的字段但是你同时还想让为旧版本写的代码仍然可用,不用怕!更新消息而不破坏已有代码是非常简单的。只要你记住下面的规则: 不要更改任何已有的字段的数值标识(tag)。 你添加的任何字段都必须是optional或repeated的。这就意味着任何使用你的“旧”消息格式的代码序列化的消息可以被你的新代码所解析,因为它们不会丢掉任何required的元素。你应该为这些元素设置合理的默认值(default values),这样新的代码就能够正确地与老代码生成的消息交互了。类似地,你的新代码创建的消息也能被你的老代码解析:老的二进制程序在解析的时候只是简单地将新字段忽略。然而,未知的字段是没有被抛弃的,此后,如果消息被序列化,未知的字段会随之一起被序列化所以,如果消息传到了新代码那里,则新的字段仍然可用。注意:对Python来说,对未知字段的保留策略是无效的。 非required的字段可以移除只要它们的标识号(tag number)在你的新消息类型中不再使用(更好的做法可能是重命名那个字段,例如在字段前添加“OBSOLETE_”前缀,那样的话,你的.proto文件的用户将来就不会无意中重新使用了那些不该使用的标识号)。 一个非required的字段可以转换为一个扩展(extension),反之亦然只要它的类型和标识号保持不变。 int32,uint32,int64,uint64,和bool是全部兼容的,这意味着你可以将这些类型中的一个转换为另外一个,而不会破坏前向、后向的兼容性。如果解析出来的数字与对应的类型不相符,那么结果就像在C+中对它进行了强制类型转换一样(例如,如果把一个64位数字当作int32来读取,那么它就会被截断为32位的数字)。 sint32和sint64是互相兼容的,但是它们与其他整数类型不兼容。 string和bytes是兼容的只要bytes是有效的UTF-8编码。 嵌套消息与bytes是兼容的只要bytes包含该消息的一个编码过的版本。 fixed32与sfixed32是兼容的,fixed64与sfixed64是兼容的。 optionalis compatible withrepeated. Given serialized data of a repeated field as input, clients that expect this field to beoptionalwill take the last input value if its a primitive type field or merge all input elements if its a message type field. Changing a default value is generally OK, as long as you remember that default values are never sent over the wire. Thus, if a program receives a message in which a particular field isnt set, the program will see the default value as it was defined in that programs version of the protocol. It will NOT see the default value that was defined in the senders code.2.8 扩展通过扩展,你可以将一个范围内的字段标识号声明为可被第三方扩展所用。然后,其他人就可以在他们自己的.proto文件中为你的消息类型声明新的字段,而不必去编辑原始文件了。让我们看个例子:message Foo / . extensions 100 to 199;这个例子表明:在消息Foo中,范围100,199之内的字段标识号被保留为扩展用。现在,其他人就可以在他们自己的.proto文件中添加新字段到Foo里了,但是添加的字段标识号要在指定的范围内例如:extend Foo optional int32 bar = 126;这个例子表明:消息Foo现在有一个名为bar的optional int32字段。当用户的Foo消息被编码的时候,数据的传输格式与用户在Foo里定义新字段的效果是完全一样的。然而,你在程序代码中访问扩展字段的方法与访问普通的字段稍有不同你生成的数据访问代码为扩展准备了特殊的访问函数来访问它。例如,下面是你如何在C+中设置bar的值:Foo foo;foo.SetExtension(bar, 15);类似地,Foo类也定义了模板函数HasExtension(),ClearExtension(),GetExtension(),MutableExtension(),以及AddExtension()。这些函数的语义都与对应的普通字段的访问函数相符。要查看更多使用扩展的信息,请参考相应语言的代码生成指南。注意:扩展可以是任何字段类型,包括消息类型。2.8.1 嵌套的扩展你可以在另一个类型的范围内声明扩展:message Baz extend Foo optional int32 bar = 126; .在此例中,访问此扩展的C+代码是:Foo foo;foo.SetExtension(Baz:bar, 15);换句话说,唯一的效果就是bar被定义在Baz的范围内。这是个引起混淆的来源:在一个消息类型中嵌套声明一个extend块并没有暗示外部类型(outer type)与扩展类型(extended type)之间有任何联系。特别地,上面的例子没有表明Baz是Foo的任何类型的子类。它所表明的仅仅是:符号bar是在Baz的内部声明的;它只是一个静态成员罢了。一个通常的设计模式就是:在扩展的字段类型的范围内定义该扩展例如,下面是一个Foo的扩展(该扩展是Baz类型的),其中,扩展被定义为了Baz的一部分:message Baz extend Foo optional Baz foo_ext = 127; .然而,并没有强制要求一个消息类型的扩展一定要定义在那个消息中。你也可以这样做:message Baz ./ This can even be in a different file.extend Foo optional Baz foo_baz_ext = 127;事实上,这种语法格式更能防止引起混淆。正如上面所提到的,嵌套的语法通常被错误地认为有子类化的关系尤其是对那些还不熟悉扩展的用户来说。2.8.2 选择可扩展的标符号在同一个消息类型中一定要确保两个用户不会扩展新增相同的标识号,否则可能会导致数据的不一致。可以通过为新项目定义一个可扩展标识号规则来防止该情况的发生。如果标识号需要很大的数量时,可以将该可扩展标符号的范围扩大至max,其中max是229- 1, 或536,870,911。如下所示:message Foo extensions 1000 to max;通常情况下在选择标符号时,标识号产生的规则中应该避开1900019999之间的数字,因为这些已经被Protocol Buffers实现中预留了。2.9 包(Package)当然可以为.proto文件新增一个可选的package声明符,用来防止不同的消息类型有命名冲突。如:package foo.bar;message Open . 在其他的消息格式定义中可以使用包名+消息名的方式来定义域的类型,如:message Foo . required foo.bar.Open open = 1; .包的声明符会根据使用语言的不同影响生成的代码。 对于C+,产生的类会被包装在C+的命名空间中,如上例中的Open会被封装在foo:bar空间中; 对于Java,包声明符会变为java的一个包,除非在.proto文件中提供了一个明确有java_package; 对于Python,这个包声明符是被忽略的,因为Python模块是按照其在文件系统中的位置进行组织的。2.9.1 包及名称的解析Protocol buffer语言中类型名称的解析与C+是一致的:首先从最内部开始查找,依次向外进行,每个包会被看作是其父类包的内部类。当然对于(foo.bar.Baz)这样以“.”分隔的意味着是从最外围开始的。ProtocolBuffer编译器会解析.proto文件中定义的所有类型名。对于不同语言的代码生成器会知道如何来指向每个具体的类型,即使它们使用了不同的规则。2.10 定义服务(Service)如果想要将消息类型用在RPC(远程方法调用)系统中,可以在.proto文件中定义一个RPC服务接口,protocol buffer编译器将会根据所选择的不同语言生成服务接口代码及存根。如,想要定义一个RPC服务并具有一个方法,该方法能够接收SearchRequest并返回一个SearchResponse,此时可以在.proto文件中进行如下定义:service SearchService rpc Search (SearchRequest) returns (SearchResponse);protocol编译器将产生一个抽象接口SearchService以及一个相应的存根实现。存根将所有的调用指向RpcChannel,它是一个抽象接口,必须在RPC系统中对该接口进行实现。如,可以实现RpcChannel以完成序列化消息并通过HTTP方式来发送到一个服

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论