先贴上官方的一个例子,来源于grpc-go的helloworld例子实现
// Copyright 2015 gRPC authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. syntax = "proto3"; option java_multiple_files = true; option java_package = "io.grpc.examples.helloworld"; option java_outer_classname = "HelloWorldProto"; package helloworld; // The greeting service definition. service Greeter { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloReply) {} } // The request message containing the user's name. message HelloRequest { string name = 1; } // The response message containing the greetings message HelloReply { string message = 1; }
1.语法协议
文件的第一行指定了你正在使用proto3语法:如果你没有指定这个,编译器会使用proto2。这个指定语法行必须是文件的非空非注释的第一个行。
2.其他语言需要调用时额外的定义
因为protoc文件是通用的一些协议,所以在不同语言编辑的时候,需要一些定义,其中这里的java就是,如果只是自己的内部go调用可以不写。
option java_package = "com.example.foo";编译器为以此作为生成的Java类的包名,如果没有该选项,则会以pb的package作为包名。
option java_multiple_files = true;该选项为true时,生成的Java类将是包级别的,否则会在一个包装类中。
option optimize_for = CODE_SIZE;该选项会对生成的类产生影响,作用是根据指定的选项对代码进行不同方面的优化。
3.包名称,与2同理,需要编译成golang文件,需要加一个包名
package helloworld,意思时包的名称为helloworld
4.定义数据结构
message HelloRequest { string name = 1; }
这里定义了一个HelloRequest 对象,go里面应该叫结构体,内部包含一个string的类型的属性,后面赋值为1,就是第几个的意思,多个属性依次赋值即可。
5.结构的嵌套
新写一个文件
syntax = "proto3"; package customer; // The Customer service definition. service Customer { // Get all Customers with filter - A server-to-client streaming RPC. rpc GetCustomers(CustomerFilter) returns (stream CustomerRequest) {} // Create a new Customer - A simple RPC rpc CreateCustomer (CustomerRequest) returns (CustomerResponse) {} } // Request message for creating a new customer message CustomerRequest { int32 id = 1; // Unique ID number for a Customer. string name = 2; string email = 3; string phone= 4; repeated Address addresses = 5; } message Address { string street = 1; string city = 2; string state = 3; string zip = 4; bool isShippingAddress = 5; } message CustomerResponse { int32 id = 1; bool success = 2; } message CustomerFilter { string keyword = 1; }
这里定义了普通的数据结构和嵌套的数据结构,可以看到CustomerRequest结构内部,嵌套了Address结构,在声明一个他的结构变量的时候,需要使用repeated(重复)这个关键字。当然,这个结构定义,也可以在内部嵌套,和后端语法其实基本一样,如下,效果是一样的。
message CustomerRequest { int32 id = 1; // Unique ID number for a Customer. string name = 2; string email = 3; string phone= 4; message Address { required string street = 1; required string city = 2; optional string state = 3; optional string zip = 4; bool isShippingAddress = 5; } repeated Address addresses = 5; }
5.数据流的定义
在上面那个新文件定义里面,看到了使用了stream这个关键字。他的作用和实际其他语言里面的流的概念其实一样,是用来持续操作的。比如你想持续写入,或者接受一个值,你就使用该关键字获取或者反馈。
详细例子讲解(以golang为例,其他语言请自行寻找): https://www.jianshu.com/p/bd35cbf279fb
6.这里出现了两个新的关键词,optional,required,意思是必须的和可选的,详细的文档可看
官方的: https://developers.google.com/protocol-buffers/docs/reference/go-generated#package
欢迎关注我们的微信公众号,每天学习Go知识