grpc的使用

在这里插入图片描述
协议缓存区(Protocol Buffers)

直观的一个表现形式就是.proto扩展名的普通文本文件,在这个文件中可以定义消息、gRPC服务。一般来讲,服务和消息搭配使用。消息相当于 我们的类,可以做为方法的参数和返回值。

协议缓存区数据被构造为消息

// 消息
message Person {
  string name = 1;
  int32 id = 2;
  bool has_ponycopter = 3;
}

如下,.proto文件。定义了一个服务和两个消息

// The greeter service definition.
service Greeter {
  // Sends a greeting  PascalCase
  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;
}
接下来,我们先了解一下,如何正确的定义一个消息
// cat.proto
package cat.bar;
message Cat{
    string name = 1;
    int32 age = 2;
}

helloworld.proto文件

syntax = "proto3";  // 指定使用proto3语法 ,不指定默认使用proto2语法。必须为文件有效的第一行

//导入另一.proto文件,以便在该3文件中使用cat.proto中定义的消息
import "cat.proto"; 
// .proto文件的包名,未指定java_package时,默认使用该包名作为生成java类的包名
package com.wanfangdata.titan; 
// 生成后的java类的包名
option java_package = "com.wanfangdata.titan.vsearch" 
// 将定义的服务和消息生成在多个文件中
option java_multiple_files = true; 
// 要生成的最外层java类(以及文件名)的类名。如果没有显示的指定这个option,则是会通过.proto的文件名转成大驼峰加上OutClass作为类名(如:HelloWorldOuterClass.java)
option java_outer_classname = "HelloWorldProto"; 

// 定义一个消息
message Person { 
  string name = 1;  // 字段名称和类型大家应该都知道,唯独对这个数字比较陌生。
  int32 id = 2;
  bool isHasHobby = 3;
  enum Corpus { // 枚举可以写在消息中,也可以引用其他消息中的枚举,也可以写在消息外边
      UNIVERSAL = 0; // 标识符必须从0开始,默认值会取第一个值  
      WEB = 1;
      IMAGES = 2;
      LOCAL = 3;
      NEWS = 4;
      PRODUCTS = 5;
      VIDEO = 6;
  }
  Corpus corpus = 4; // 上边定义了枚举,在这里引用使用
  repeated Student student = 5;  // 使用其他的Message类型
  Cat cat = 6; // 引用定义的其他消息类型
  //cat.bar.Cat cat = 6; 直接连package的包加上,可以防止多个.proto文件中都含有消息Cat冲突
  message Son { // 可以再消息中直接定义一新的消息,然后直接引用
      string name = 1;
      int32 age = 2;  
  }
  repeated Son son = 6;
  // oneof 可以有多个可选的字段,只能设置其中一个字段,如果设置多个字段,只有最后一个生效,其他的都会被清除
  oneof test_oneof{
      string name = 1;
      int32 age = 2;  
  }
  //Maps类型
  //其中 key_type 可以是任何整数或字符串类型(任何标量类型除浮点类型和 bytes)。   
  //请注意,枚举不是有效的 key_type。value_type 可以是除 map 之外的任何类型。
  map<key_type, value_type> map_field = N;
}
message Student{
    string name = 1;
    int32 age = 2;
    Person.Son son = 3; // 引用了person消息的子消息son
}
//一个.proto文件中可以定义多个消息,一般来讲,是定义多个相关的消息,比如请求的类型和响应的类型
分配标识号

我们看到在上边的定义消息中,给每一个字段都定义了一个唯一的数字值。这些数字是用来在消息的二进制格式中识别各个字段的,一旦开始使用,就不能再改变。
注意:

  • 【1,15】范围内的标识号在编码的时候会占用一个字节。
  • 【16,2047】范围的标识号在编码的时候则占用2个字节。
    所以应该为那些频繁出现的消息元素,保留【1,15】范围的标识号。切记,要为讲来有可能添加的、频繁出现的字段预留一些标识号。
  • 最小的标识号可以从1开始,最大到2^29-1。不可以使用其中的【19000,19999】的标识号,protobuf协议实现中对这些进行了预留。
    如果非要使用,在使用protoc进行编译的时候,会报如下ptotoc did exit cleanly.失败的警告。
Failed to execute goal org.xolstice.maven.plugins:protobuf-maven-plugin:0.6.1:compile-cpp (default-cli) on project grpc-java-springboot-demo: protoc did not exit cleanly. Review output for more information.
指定字段规则

消息的字段可以是以下情况之一:

  • singular (默认):一个格式良好的消息可以包含该字段可以出现0或者1次。
  • repeated:在一个格式良好的消息汇总,这种字段可以重复任意多次(包括0次)。重复的值的顺序会被保留。
添加注释:

这个和平时用的一样,单行和多行注释都可以 // 或者 /* */

从.proto文件生成了什么?

对于java来说,编译器会为每个消息类型生成一个.java文件,以及一个特殊的Builder类(该类是用来创建消息类接口的)。
对于C#语言,编译器会为每一个.proto文件创建一个.cs文件,为每一个消息类型都创建一个类来操作。

标量类型

一个标量消息字段可以含有一个如下的类型---- 该表格展示了定义于.proto文件中的类型,以及与之对应的,在自动生成的访问类中定义的类型。
在这里插入图片描述

默认值

在.proto文件中可以设置默认中吗,在proto2语法中可以,但是在proto3语法中不支持。字段的默认值,相应的字段在被解析的对象中会被设置默认值。这些默认值是和类型有关系的。

  • 字符串默认值为空字符串
  • 字节类型默认值为空字节。
  • 布尔类型默认值为false
  • 数值类型默认值为0
  • 枚举类型默认值是其定义中的第一个值,它必须为0
  • 消息类型的默认值没有设置。它的具体值与使用的编程语言有关。
  • repeated字段的默认值为空(通常是相应编程语言的空列表)
定义服务

我们的服务接口,也是定义在.proto文件中的,和消息定义在一起。

JSON映射

proto3支持标准的JSON编码,使得在不同的系统直接共享数据 变得简单。下表列出的是基础的类型对照。

在json编码中,如果某个值被设置为null或者丢失,在映射为protobuf的时候会转换为相应的默认值。 在protobuf中如果一个字段是默认值,在映射为json编码的时候,这个默认值会被忽略以节省空间。可以通过选项设置,使得json编码输出中字段带有默认值。

grpcurl使用

  1. 没有请求参数:
# no TLS
grpcurl -plaintext grpc.server.com:80 my.custom.server.Service/Method
  1. 有请求参数

使用-d添加参数,参数必须在服务地址和方法名前边

grpcurl -d '{"id": 1234, "tags": ["foo","bar"]}' \
    grpc.server.com:443 my.custom.server.Service/Method
  1. 列出所有的服务
grpcurl localhost:50051 list  列出该连接下的所有的服务
// grpc.reflection.v1alpha.ServerReflection
//helloworld.Greeter

列出服务下的所有方法

grpcurl localhost:50051 list helloworld.Greeter 
// helloworld.Greeter.SayHello

如果还想了解方法的细节,可以使用grpcurl提供的describe子命令查看更详细的描述信息:

grpcurl -plaintext localhost:50051 describe helloworld.Greeter 

在这里插入图片描述
在获取到方法的参数和返回值类型之后,还可以继续查看类型的信息。下面是用describe命令查看参数 .helloworld.HelloRequest类型的信息:

grpcurl -plaintext localhost:50051 describe .helloworld.HelloRequest

在这里插入图片描述
注意:
该命令需要开启反射服务,否则的话会提示如下错误
在这里插入图片描述
开启反射服务:

  1. 导入依赖

在这里插入图片描述

  1. 修改服务端,将反射服务加入

在这里插入图片描述
当没有配置这个公钥和私钥时,会报如下错误。grpcurl默认需要走tls校验的,可以通过-cert-key参数设置公钥和私钥文件
对于没有没用tls协议的grpc服务,通过-plaintext参数忽略tls证书的验证过程。如果是Unix Socket协议,则需要指定-unix参数。
在这里插入图片描述

  1. 请求服务接口数据
grpcurl -d '{"id": 1234, "tags": ["foo","bar"]}' \
    grpc.server.com:443 my.custom.server.Service/Method

在这里插入图片描述
注意:
在window下输入的json串,外层使用双引号,或者直接不写,单引号报错
在这里插入图片描述
在window下输入json串,json的字段需要进行转义,如果不进行转义,会报错。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值