.net gRPC 初步上手

1. gRPC

    gRPC是谷歌推出的语言无关、平台无关的高性能RPC库,现已成为微服务集成的主要通讯手段,微软从.net core3.0开始将gRPC作为首选,系统学习可以看微软的文档。关于proto3的语法,这篇写的不错。

2. 编辑proto文件

    注意:proto文件应保存到解决方案中(例如Protos文件夹),而不是某项目下面,否则编译时生成的cs文件位置不对。

    根据proto3的语法,把原来的业务实体定义为message,远程接口定义为 service。

    用 csharp_namespace 指定proto编译得到的类的命名空间。

    可以通过 import “***.proto” 的方式引用其他message类型。

    proto编译为c#时,属性名自动转为Camol大小写,像u_int32就会编译为UInt32,而UInt32编译为Uint32,所以中间需要大写的记得加_。 

    例子一,定义 common.proto,存放常用的Empty, RequestId 等。

syntax = "proto3";
option csharp_namespace = "Common";
message Empty{}
message BoolResponse{
  bool response = 1;
}
message IntResponse{
  int32 response = 1;
}
message StringResponse{
  string response = 1;
}
message RequestId{
  int32 id = 1;
}
enum ReadWrite
{
  None = 0;
  Read = 1;
  Write = 2;
  Both = 3;
}

    例子二,业务对象定义tagmessage.proto,引用了common.proto里面的ReadWrite枚举,以及List,Dictionary。

syntax = "proto3";
import "common.proto";
option csharp_namespace = "Models";
message Tag {
  uint64 tagid = 1;
  string name = 2;
  string unit = 3;
  string source = 4;
  string descr = 5;
  ReadWrite rw=6;
  double range_low=7;
  double range_up=8;
  bool compress=9;
  string default_value=10;
}
message TagList {
  repeated Tag items = 1;
}
message TagMap{
  map<uint64,Tag> items = 1;
}

    例子三,CRUD 服务接口定义tagrpc.proto。

syntax = "proto3";
import "common.proto";
import "tagmessage.proto";
option csharp_namespace = "Services";

service TagRPC {
  rpc GetAll (Empty) returns (TagList);
  rpc Get (RequestId) returns (Tag);
  rpc GetByName (RequestName) returns (Tag);
  rpc Insert (Tag) returns (Tag);
  rpc Update (Tag) returns (Tag);
  rpc Remove (RequestId) returns (BoolResponse);
}

    例子四,使用Nullable类型

import "google/protobuf/wrappers.proto";
...
message TestMessage {
    ...
    google.protobuf.Int32Value nullableInt = 5; //DoubleValue for double?
}

3. 将proto文件添加到.net standara2.1类库

    创建 .net standard2.1 类库,用nuget添加Google.Protobuf(3.13.0),Grpc.Net.ClientFactory(2.32.0), Grpc.Tools(2.32.0);

    双击工程,在.csproj文件中加入(.net standard2.1项目右键>添加>服务引用 里面没找到 gRPC 选项):

  <ItemGroup>
    <Protobuf Include="..\Protos\common.proto" GrpcServices="Both">
      <Link>Protos\common.proto</Link>
    </Protobuf>
    <Protobuf Include="..\Protos\tagmessage.proto" GrpcServices="Both">
      <Link>Protos\tagmessage.proto</Link>
    </Protobuf>
  </ItemGroup>

    编译工程,如果proto文件语法有错误,根据提示修改。

    如果编译通过,那么你就有了一个实体定义的类库,可以被别的 .net 项目引用了。注意,此步骤不是必须的,官方Greeter例子就只有client、server两个项目。

    如果需要,可以扩展message生成的类,因为编译出来的是 partial class.

public sealed partial class Tag
{
    //扩展
}

4. 将proto文件添加到.net core 服务

    新建 Asp.net core gRPC项目,会自动添加Google.Protobuf(3.13.0),Grpc.Net.ClientFactory(2.32.0), Grpc.Tools(2.32.0) 这几个库。

    在项目上点右键>添加>服务引用,(批量)选择proto文件,生成类型:服务器。

    后面就是 继承 Services.TagRPC.TagRPCBase,override CRUD方法做具体实现了。

5. gRPC不支持null

    proto3协议里面不支持null,因为不是所有编程语言都有null,protobuf也不知道怎么对0字节的null进行编码。在proto3文件中可以用Empty代替null,在服务实现时要小心:返回值不能是null,虽然C#允许 await Task.FromResult(null),但经过gRPC时会抛出 RPCException ,状态 Cancelled,所以服务返回值如果是引用类型要返回一个非null实例。

总结

    gRPC在微软与谷歌的合作下为.net 开发人员做了很好的整合,虽然先编辑proto再写代码这种方式还需要习惯,但学习成本不高,proto一旦确定那么客户端随便用什么语言都可以写,想想还是很牛叉的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值