7.NET中GRPC进阶,可空类型,返回集合

 

1.添加两个类,一个类型可空,一个不可空

public class Person1
{
    public int Id { get; set; }
    public double Money { get; set; }
    public float Weight { get; set; }
    public bool Gender { get; set; }
    public long PhoneNum { get; set; }
    public string Email { get; set; }
    public System.DateTime Birthday { get; set; }
}

 

public class Person2
{
    public int? Id { get; set; }
    public double? Money { get; set; }
    public float? Weight { get; set; }
    public bool? Gender { get; set; }
    public long? PhoneNum { get; set; }
    public string? Email { get; set; }
    public DateTime? Birthday { get; set; }
}

 

 

2.在GrpcServer项目中的Apis文件夹中添加

 public interface IPersonService
    {
        Person1 GetPerson1();
        
        Person2 GetPerson2();
    }
public class PersonServiceImpl:IPersonService
{
    public Person1 GetPerson1()
    {
        var person = new Person1
        {
            Id = 1,
            Money = 3000.00d,
            Weight = 1.78f,
            Gender = true,
            PhoneNum = 13823784433,
            Email = "1310734881@qq.com",
            Birthday = DateTime.Parse("2000-02-20").ToUniversalTime()
        };
        return person;
    }

    public Person2 GetPerson2()
    {
        var person = new Person2
        {
            Id = 1,
            Money = 3000.00d,
            Weight = 1.78f,
            Gender = true,
            PhoneNum = 13823784433,
            Email = "1310734881@qq.com",
            Birthday = DateTime.Parse("2000-02-20")
        };
        return person;
    }
}

 

3.然后再Protos文件中添加person.proto文件

syntax = "proto3";
option csharp_namespace = "GrpcServer";
package person;
// 时间类型
import "google/protobuf/timestamp.proto";
// 无参/无返回值
import "google/protobuf/empty.proto";
// 引用可空类型
import "google/protobuf/wrappers.proto";


message Person1Dto{
  int32 id=1;
  double money=2;
  float weight=3;
  bool gender=4;
  int64 phone_num=5;
  string email=6;
  google.protobuf.Timestamp birthday=7;
}

// 出参1,返回类型
message Person1Response{
    Person1Dto person =1;
}
//入参,传入参数
message Person1Request{
  
}


// 可空类型
message Person2Dto{
  google.protobuf.Int32Value id = 1;
  google.protobuf.DoubleValue money = 2;
  google.protobuf.FloatValue weight = 3;
  google.protobuf.BoolValue gender = 4;
  google.protobuf.Int64Value phone_num = 5;
  google.protobuf.StringValue email = 6;
  google.protobuf.Timestamp birthday = 7;
}
//出参,返回类型 message Person2Response{ Person2Dto person
=1; } //入参,参数 集合请求对象 message CollectionRequest{ } // 集合响应对象 message CollectionResponse{ repeated Person1Dto person=1; map<int32,Person1Dto> dict=2; } //服务 service PersonService{ rpc GetPerson1(google.protobuf.Empty) returns (Person1Response); rpc GetPerson2(google.protobuf.Empty) returns (Person2Response); // 返回集合 rpc GetCollection(CollectionRequest) returns (CollectionResponse); }

 

看GrpcServer.csproj内是否生成

 <ItemGroup>
      <PackageReference Include="Grpc.AspNetCore" Version="2.56.0" />
        <ProtoBuf Include="Protos/user.proto" GrpcService="Server" />
        <ProtoBuf Include="Protos/person.proto" GrpcService="Server" />
    </ItemGroup>

 

在Services文件夹内添加PersonServiceGrpc.cs

public class PersonServiceGrpc:PersonService.PersonServiceBase
{
    private readonly IPersonService _personService;

    public PersonServiceGrpc(IPersonService personService)
    {
        _personService = personService;
    }

    public override Task<Person1Response> GetPerson1(Empty request, ServerCallContext context)
    {
         Person1 person1 =  _personService.GetPerson1();
         Person1Response response = new();
         response.Person = new()
         {
             Id = person1.Id,
             Money = person1.Money,
             Weight = person1.Weight,
             Gender = person1.Gender,
             PhoneNum = person1.PhoneNum,
             Email = person1.Email,
             // timestamp 类型需要UTC时间
             Birthday = DateTime.Parse("2000-02-20").ToUniversalTime().ToTimestamp()
         };
         

         return Task.FromResult(response);
    }

    public override Task<Person2Response> GetPerson2(Empty request, ServerCallContext context)
    {
        Person2 person2 =  _personService.GetPerson2();
        Person2Response response = new();
        response.Person = new()
        {
            Id = person2.Id,
            Money = person2.Money,
            Weight = person2.Weight,
            Gender = person2.Gender,
            PhoneNum = person2.PhoneNum,
            Email = person2.Email,
            // timestamp 类型需要UTC时间
            Birthday = DateTime.Parse("2000-02-20").ToUniversalTime().ToTimestamp()
        };
        
        return Task.FromResult(response);
    }

    public override Task<CollectionResponse> GetCollection(CollectionRequest request, ServerCallContext context)
    {
        CollectionResponse response = new();
        Person1Dto dto1 = new()
        {
            Id = 1,
            Money = 3000.00d,
            Weight = 1.78f,
            Gender = true,
            PhoneNum = 13823784433,
            Email = "1310734881@qq.com",
            Birthday = DateTime.Parse("2000-02-20").ToUniversalTime().ToTimestamp()
        };
        Person1Dto dto2 = new()
        {
            Id = 2,
            Money = 2000.00d,
            Weight = 2.78f,
            Gender = true,
            PhoneNum = 13823782222,
            Email = "1310734881@qq.com",
            Birthday = DateTime.Parse("2022-02-22").ToUniversalTime().ToTimestamp()
        };
        List<Person1Dto> list = new() {dto1, dto2};

        response.Person.AddRange(list);
        response.Dict.Add(1,dto1);
        response.Dict.Add(2,dto2);

        return Task.FromResult(response);
    }
}

 

在Program.cs添加注册服务和添加管道

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddGrpc();//添加GRPC服务

//设置GRPC为http2.0
builder.WebHost.UseKestrel(p =>
{
    p.ConfigureEndpointDefaults(opt =>
    {
        opt.Protocols = HttpProtocols.Http2;
    });
});


builder.Services.AddTransient<IUserService, UserServiceImpl>();
builder.Services.AddTransient<IPersonService, PersonServiceImpl>();



var app = builder.Build();


app.MapGrpcService<UserServiceGrpc>();
app.MapGrpcService<PersonServiceGrpc>();

app.Run();

 

客户端

gRPC 与 HttpClientFactory 的集成提供了一种创建 gRPC 客户端的集中方式。 它可用作 配置独立gRPC 客户端实例

安装包:Grpc.Net.ClientFactory

GrpcClient客户端项目中的Protos文件夹中添加person.proto文件

syntax = "proto3";
option csharp_namespace = "GrpcClient";
package person;
// 时间类型
import "google/protobuf/timestamp.proto";
// 无参/无返回值
import "google/protobuf/empty.proto";
// 引用可空类型
import "google/protobuf/wrappers.proto";


message Person1Dto{
  int32 id=1;
  double money=2;
  float weight=3;
  bool gender=4;
  int64 phone_num=5;
  string email=6;
  google.protobuf.Timestamp birthday=7;
}

// 出参1
message Person1Response{
  Person1Dto person =1;
}

message Person1Request{

}


// 可空类型
message Person2Dto{
  google.protobuf.Int32Value id = 1;
  google.protobuf.DoubleValue money = 2;
  google.protobuf.FloatValue weight = 3;
  google.protobuf.BoolValue gender = 4;
  google.protobuf.Int64Value phone_num = 5;
  google.protobuf.StringValue email = 6;
  google.protobuf.Timestamp birthday = 7;
}
message Person2Response{
  Person2Dto person =1;
}

// 集合请求对象
message CollectionRequest{

}

// 集合响应对象
message CollectionResponse{
  repeated Person1Dto person=1;
  map<int32,Person1Dto> dict=2;
}




service PersonService{
  rpc GetPerson1(google.protobuf.Empty) returns (Person1Response);
  rpc GetPerson2(google.protobuf.Empty) returns (Person2Response);

  // 返回集合
  rpc GetCollection(CollectionRequest) returns (CollectionResponse);
}

生成后查看GrpcClient.csproj是否以下

 <ItemGroup>
    <Protobuf Include="Protos\person.proto">
      <GrpcServices>Client</GrpcServices>
      <Access>Public</Access>
      <ProtoCompile>True</ProtoCompile>
      <CompileOutputs>True</CompileOutputs>
      <OutputDir>obj\Debug\net7.0\</OutputDir>
      <Generator>MSBuild:Compile</Generator>
    </Protobuf>
    <Protobuf Include="Protos\user.proto">
      <GrpcServices>Client</GrpcServices>
      <Access>Public</Access>
      <ProtoCompile>True</ProtoCompile>
      <CompileOutputs>True</CompileOutputs>
      <OutputDir>obj\Debug\net7.0\</OutputDir>
      <Generator>MSBuild:Compile</Generator>
    </Protobuf>
  </ItemGroup>
 
若要注册 gRPC 客户端,可在 Program.cs 中的应用入口点处的 WebApplicationBuilder 的实例中使用通用的 AddGrpcClient 扩展方法,并指定 gRPC 类型化客户端类和服务地址
Action<GrpcClientFactoryOptions> opt = p =>
{
    p.Address = new Uri("http://localhost:5023");
};
builder.Services.AddGrpcClient<UserService.UserServiceClient>(opt);
builder.Services.AddGrpcClient<PersonService.PersonServiceClient>(opt);

 

添加PersonController控制器

[ApiController]
[Route("[controller]/[action]")]
public class PersonController : ControllerBase
{
    private readonly PersonService.PersonServiceClient _personServiceClient;


    public PersonController(PersonService.PersonServiceClient personServiceClient)
    {
        _personServiceClient = personServiceClient;
    }

    [HttpGet]
    public async Task<IActionResult> GetPerson1()
    {
        // 创建通信频道
        // var channel = GrpcChannel.ForAddress("http://localhost:5023");
        // var client = new PersonService.PersonServiceClient(channel);
        // var response = client.GetPerson1Async(new Empty());
        // // 等待获取头
        // var resultHeaders = await response.ResponseHeadersAsync;
        // var resultResponse = await response.ResponseAsync;

        var response = _personServiceClient.GetPerson1(new Empty());

        return Ok(response.Person);
    }
    
    [HttpGet]
    public IActionResult GetPerson2()
    {
        // 创建通信频道
        // var channel = GrpcChannel.ForAddress("http://localhost:5023");
        // var client = new PersonService.PersonServiceClient(channel);
        var response = _personServiceClient.GetPerson2(new Empty());

        return Ok(response.Person);
    }
    
    [HttpGet]
    public IActionResult GetCollection()
    {
        // 创建通信频道
        // var channel = GrpcChannel.ForAddress("http://localhost:5023");
        // var client = new PersonService.PersonServiceClient(channel);
        var response = _personServiceClient.GetCollection(new CollectionRequest());

        return Ok(new{response.Person,response.Dict});
    }
}

 

 

 

 

posted @ 2024-02-18 13:54  野码  阅读(143)  评论(0编辑  收藏  举报