先贴上官方的一个例子,来源于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
有疑问加站长微信联系(非本文作者)