AspNetCore中 使用 Grpc 简单Demo

2022-10-12,,,

为什么要用Grpc

跨语言进行,调用服务,获取跨服务器调用等

目前我的需要使用 我的抓取端是go 写的 查询端用 Net6 写的 导致很多时候 我需要把一些临时数据写入到 Redis 在两个服务器进行处理

参考地址:

哔哩哔哩杨旭大佬:https://www.bilibili.com/video/BV1eE411T7GC/?spm_id_from=333.999.0.0

强烈建议去看一遍杨旭大佬讲的这篇Grpc 没有那么繁琐 清晰明了

1、依赖安装:

Grpc.AspNetCore Server 端包

2、编写proto 文件

点击查看代码
syntax = "proto3";

option csharp_namespace= "GrpcServer.Web.Protos";

message Employee{
int32 id = 1;
int32 no = 2;
string firstName = 3;
string lastName =4;
float salary = 5; } message GetByNoRequest{
int32 no =1;
} message EmployeeResponse{
Employee employee =1; } message GetAllRequest{ } message AddPhotoRequest{
bytes data = 1; } message AddPhotoResponse{
bool isOK = 1;
} message EmployeeRequest{
Employee employee = 1;
} service EmployeeService {
rpc GetByNo(GetByNoRequest) returns (EmployeeResponse);
rpc GetAll(GetAllRequest) returns (stream EmployeeResponse);
rpc AddPhoto(stream AddPhotoRequest) returns (AddPhotoResponse);
rpc Save (EmployeeRequest) returns(EmployeeResponse);
rpc SaveAll(stream EmployeeRequest) returns(stream EmployeeResponse);
}

3、编写Server端代码

在编写服务端代码之前,我们需要对proto 文件进行生成代码

如上图:1)我们要先进行勾选Build Action 选择,如图所示,

因为我们这里需要的只是 Server 端,选择生成Server Only

2) 选择这两个之后 我们需要重新生成一下项目

EmployeeService.EmployeeServiceBase 是我们Proto 生成的代码,我们要去重写父类的这些方法
点击查看代码
   public class MyEmployeeService : EmployeeService.EmployeeServiceBase
{
private readonly ILogger<MyEmployeeService> _logger; public MyEmployeeService(ILogger<MyEmployeeService> logger)
{
_logger = logger;
} public override async Task<EmployeeResponse>
GetByNo(GetByNoRequest request, ServerCallContext context)
{
var employee = InMemoryData.Employees.SingleOrDefault(x => x.No == request.No);
if (employee != null)
{
var response = new EmployeeResponse
{
Employee = employee
};
return await Task.FromResult(response);
}
throw new Exception($"employee is not found :{request.No}"); }
public override async Task GetAll(GetAllRequest request, IServerStreamWriter<EmployeeResponse> responseStream, ServerCallContext context)
{
foreach (var item in InMemoryData.Employees)
{
await responseStream.WriteAsync(new EmployeeResponse
{
Employee = item
});
}
//return base.GetAll(request, responseStream, context);
} public override async Task<AddPhotoResponse> AddPhoto(
IAsyncStreamReader<AddPhotoRequest> requestStream
, ServerCallContext context)
{
Metadata md = context.RequestHeaders;
foreach (var item in md)
{
Console.WriteLine($"{item.Key}:{item.Value}");
} var data = new List<byte>();
while (await requestStream.MoveNext())
{
Console.WriteLine($"Received: {requestStream.Current.Data.Length}");
data.AddRange(requestStream.Current.Data);
}
Console.WriteLine($"data file with {data.Count} bytes");
return new AddPhotoResponse
{
IsOK = true
}; } public override async Task SaveAll(
IAsyncStreamReader<EmployeeRequest> requestStream
, IServerStreamWriter<EmployeeResponse> responseStream
, ServerCallContext context)
{
while (await requestStream.MoveNext())
{
var employee = requestStream.Current.Employee;
lock (this)
{
InMemoryData.Employees.Add(employee);
}
await responseStream.WriteAsync(new EmployeeResponse
{
Employee = employee
});
}
Console.WriteLine("Employees");
foreach (var item in InMemoryData.Employees)
{
Console.WriteLine(item);
}
//return base.SaveAll(requestStream, responseStream, context);
}
}

4、编写Client客户端代码

    我们把服务端的Proto 文件复制一份到Client 端代码 生成一份Client 代码如下图

    需要注意

在编写客户端代码的时候,我遇到了一个错误,提示证书验证失败!,(没有配置证书)

所以我们要加上不对证书进行验证

使用 GrpcChannelOptions() 对证书验证

 using var channel = GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions()
{
HttpClient = null,
HttpHandler = new HttpClientHandler
{
//方法一
ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
//方法二
//ServerCertificateCustomValidationCallback = (a, b, c, d) => true
}
});

Demo 地址:https://gitee.com/Lovely_Rabbit/basic-principle-exercise

AspNetCore中 使用 Grpc 简单Demo的相关教程结束。

《AspNetCore中 使用 Grpc 简单Demo.doc》

下载本文的Word格式文档,以方便收藏与打印。