手机网站是怎么做的,简单的购物网站项目,百度搜索页面,网络推广培训有哪些课程Protobuf3笔记文件后缀定义Proto的文件应以.proto为后缀。语法版本Proto文件的首行应指定语法版本#xff1a;syntax proto3; // proto2定义字段在消息中#xff0c;每个字段以下列方式定义#xff1a;type filed tag ;如…Protobuf3笔记文件后缀定义Proto的文件应以.proto为后缀。语法版本Proto文件的首行应指定语法版本syntax proto3; // proto2定义字段在消息中每个字段以下列方式定义type filed tag ;如message SearchRequest {string query 1;int32 page_number 2;int32 result_per_page 3;}标签数字出于性能考虑在消息中常用字段的标签最好小于15。这样可以降低消息序列化后的体积。多消息一个Proto文件中可以定义多个消息。如message SearchRequest {// ...}message SearchResponse {// ...}注释Proto使用C风格的注释。编译输出对于Cprotobuf为每个消息生成一个类为每个proto文件生成一个.h头文件和一个.cc源代码文件。对Javaprotobuf为每个消息生成一个类和一个Builder类。对于Goprotobuf为每个消息生成一个.pb.go源代码文件和一个结构体。对Objective-Cprotobuf为每个proto文件生成一个pbobjc.h头文件和一个pbobjc.m文件为每个消息生成一个类。常用标量类型boolstringbytesint32int64uint32uint64doublefloat默认值类型默认值boolfalsebytes[]numeric0enumFirstElementFieldnull枚举类型message SearchRequest {string query 1;int32 page_number 2;int32 result_per_page 3;enum Corpus {UNIVERSAL 0;WEB 1;IMAGES 2;LOCAL 3;NEWS 4;PRODUCTS 5;VIDEO 6;}Corpus corpus 4;}message EnumAllowingAlias {option allow_alias true;UNKNOWN 0;STARTED 1;RUNNING 1;}引用其他消息类型message SearchResponse {repeated Result results 1;}message Result {string url 1;string title 2;repeated string snippets 3;}引用其他proto文件import myproject/other_protos.proto;protoc参数-I/–proto_path 指定proto文件目录。内置类型message SearchResponse {message Result {string url 1;string title 2;repeated string snippets 3;}repeated Result results 1;}message SomeOtherMessage {SearchResponse.Result result 1;}更新消息字段标签不得改动已存在的字段标签。新生成的代码可以解析旧消息。新增的字段会被设置为默认值。旧代码也可以解析新消息新增的字段会被忽略。删除字段字段可以被删除。但已使用过的标签不得重复使用。bytes和string当字符串是UTF-8编码时bytes和string可以兼容。Any消息Any消息是一个占位符表示任意类型。使用Any消息时需要引用google/protobuf/any.proto。import google/protobuf/any.proto;message ErrorStatus {string message 1;repeated google.protobuf.Any details 2;}NetworkErrorDetails details ...;ErrorStatus status;status.add_details()-PackFrom(details);ErrorStatus status ...;for (const Any detail : status.details()){if (detail.Is()){NetworkErrorDetails network_error;detail.UnpackTo(network_error);...}}OneOf消息OneOf提供了一种类似C语言union结构体的机制来降低存储体积。message SampleMessage {oneof test_oneof {string name 4;SubMessage sub_message 9;}}SampleMessage message;message.set_name(Joe);assert(message.has_name());Map消息Map可以定义一组键值对。map projects 3;声明包。package foo.bar;定义服务service SearchService {rpc Search (SearchRequest) returns (SearchResponse);}在Go中使用protobuf示例protopackage tutorial;option java_package com.example.tutorial;option java_outer_classname AddressBookProtos;message Person {required string name 1;required int32 id 2;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;}生成的代码调用方法import (github.com/golang/protobuf/protopb path/to/generated/pb/file)// ...p : pb.Person {Id: 1234,Name: John Doe,Email: jdoeexample.com,Phones: []*pb.Person_PhoneNumber {{Number: 555-4321, Type: pb.Person_HOME},},}out, err : proto.Marshal(p)q : pb.Person{}err : proto.Unmarshal(in, q)proto.MessageType(name string) reflect.Typeproto.Clone(pb Message) MessageAny消息在Go中的用法Any消息可以表示任意类型的消息。在Go中使用Any消息的示例如下import github.com/golang/protobuf/ptypesimport github.com/golang/protobuf/protoimport path/to/generated/pb// message Foo {// google.protobuf.Any bar 1;// }// message Bar {// uint32 x 1;// }bar : pb.Bar{X: 1,}body, err : ptypes.MarshalAny(bar)if err ! nil {log.Fatal(err)}foo : pb.Foo{Bar: body,}注意事项在使用proto.Unmarshal(buf, message)对消息进行反序列化时缓冲区buf的长度应当等于消息的实际长度。否则会报告如下错误消息 proto: protocol.Message: illegal tag 0 (wire type 0)在Java中使用protobuf示例protopackage tutorial;option java_package com.example.tutorial;option java_outer_classname AddressBookProtos;message Person {required string name 1;required int32 id 2;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;}生成的代码// Personpublic boolean hasName();public String getName();public boolean hasId();public int getId();public boolean hasEmail();public String getEmail();public List getPhoneList();public int getPhoneCount();public PhoneNumber getPhone(int index);// Person.Builderpublic boolean hasName();public java.lang.String getName();public Builder setName(String value);public Builder clearName();public List getPhoneList();public int getPhoneCount();public PhoneNumber getPhone(int index);public Builder setPhone(int index, PhoneNumber value);public Builder addPhone(PhoneNumber value);public Builder addAllPhone(iterable value);public Builder clearPhone();调用方法Person john Person.newBuilder().setId(1234).setName(John).addPhone(Person.PhoneNumber.newBuilder().setNumber(555-4321).setType(Person.PhoneType.HOME)).build();john.writeTo(outputStream);Person walliam Person.parseForm(inputStream);使用Gradle生成protobufgoogle提供了生成protobuf的gradle插件名称是com.google.protobuf。在使用时需要在build.gradle中加入buildscript {repositories {mavenCentral()}dependencies {classpath com.google.protobuf:protobuf-gradle-plugin:0.8.1}}apply plugin: javaapply plugin: com.google.protobufprotobuf {generatedFilesBaseDir $projectDir/srcprotoc {// use local protoc// path /usr/local/bin/protoc// or, get from repoartifact com.google.protobuf:protoc:3.3.0}plugins {grpc {artifact io.grpc:protoc-gen-grpc-java:1.4.0}}generateProtoTasks {all()*.plugins {grpc {}}}}repositories {mavenCentral()}dependencies {compile com.google.protobuf:protobuf-java:3.3.1compile io.grpc:grpc-netty:1.4.0compile io.grpc:grpc-protobuf:1.4.0compile io.grpc:grpc-stub:1.4.0/* for Android client, usecompile io.grpc:grpc-okhttp:1.4.0compile io.grpc:grpc-protobuf-lite:1.4.0compile io.grpc:grpc-stub:1.4.0*/}sourceSets {main {proto {srcDir src/main/protobufinclude **/*.proto}}}然后执行gradle build如果只需要生成java源代码文件可以执行gradle generateProto参考资料修订记录2016年05月03日 建立文档。2016年08月11日 修订。2017年07月28日 改为rst格式。2017年07月28日 增加gradle部分。2017年08月04日 修订例子。2017年08月07日 增加在Go中使用Any消息的例子。2018年08月06日 修正错别字修改日期格式。