.NET Core With gRpc

.NET Core With gRpc

gRpc 是 Google 开源的一个与语言无关的高性能远程过程调用 (RPC) 框架,RPC(Remote Procedure Call Protocol)远程过程调用协议。一个通俗的描述是:客户端在不知道调用细节的情况下,调用存在于远程计算机上的某个对象,就像调用本地应用程序中的对象一样。

在 gRpc 里,客户端可以直接调用不同机器上的服务应用的方法,就像是本地对象一样,所以创建分布式应用和服务就很简单了。在很多 RPC(Remote Procedure Call Protocol)系统里,gRpc 是基于定义一个服务,指定一个可以远程调用的带有参数和返回类型的的方法。在服务端,服务实现这个接口并且运行 gRpc 服务处理客户端调用。

Google Protobuf

gRpc 使用协议缓冲作为传输格式,gRpc 使用Google Protobuf,使用协议缓冲的第一步是在 proto file 里为数据定义你想序列化的结构:可以是普通的.proto 扩展的文本文件。协议缓冲数据结构为 messages,每条 message 是一个小的逻辑记录的信息包含一些 name-value 对名为 fields,比如:

1
2
3
4
5
message Person {
string name = 1;
int32 id = 2;
bool has_ponycopter = 3;
}

然后,一旦你指定了你的数据结构,使用协议缓冲解析器 protoc 生成数据访问类在 proto 定义的语言。这些为每个字段(比如 name()和 set_name())和方法序列化/解析整个结构到/从 raw bytes 提供了简单的访问器 - 比如,你选择的语言是 C++,对上面的例子运行编译会生成一个 Person 类。然后就可以在应用里使用这个类去 populate,序列化和获取 Person 协议缓冲 messages。

gRpc Service

接下来我们就开始编写我们的第一个 gprc 服务,然后演示调用,首先准便好 .NET Core With gRpc 的开发环境,我们这里使用 VS2019 创建模板,需要在安装的时候勾选如下 Workloads:


打开 VS2019 搜索模板 gRpc

创建项目成功以后,会自动生成 Protos 文件夹,里头会有一个默认的 protobuf 文件 -> greet.proto,并且已经定义了一个 request data 和 response data 以及一个 service。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
syntax = "proto3";
option csharp_namespace = "gRpcService";
package greet;

service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply);
}

message HelloRequest {
string name = 1;
}

message HelloReply {
string message = 1;
}

模板也为我们创建相应的服务文件 -> GreeterService.cs,我们打开这个文件,然后对我们在 protobuf 文件中定义的服务进行实现,实现 SayHello 方法。

1
2
3
4
5
6
7
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
{
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
});
}

短短的几行代码我就已经实现了一个最简陋的 gRpc 服务,我们来看一下我们做了什么,我们定义了一个 request data -> HelloRequest,这用于我们发送请求的时候提交一些我们自己的数据,然后我们定义了一个 response data -> HelloReply,这用于响应我们请求的同时返回一些数据,然后我们定义了一个 gRpc service -> SayHello, 这定义了这个请求应该如何接收参数以及返回数据。

我们使用 dotnet run 命令,进行编译以及启动。

这样我们的 gRpc 服务就已经跑起来了,大家也可以在 launchSettings.json 中配置启动的端口以及域名。

gRpc Client

我们现在实现一个客户端去调用我们的 gRpc 服务,在当前解决方案中添加一个 .NET Core Console 项目,然后在 Dependencies 上面右键点击 Add Connected Service ,然后添加一个 gRpc 服务,如图所示。

选择 gRpc

选择我们刚刚创建的 gRpc 服务中 proto 文件

然后等待 VS 分析以及校验完,如果没有问题的话,就会显示成功,并且会将这个 proto 文件拷贝一份到当前项目的 Protos 文件夹下:

然后我们发送我们的第一个 gRpc 服务器调用,我们就直接写到主函数了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using Grpc.Net.Client;
using GrpcService;
using System;
using System.Net.Http;

namespace GrpcClient
{
class Program
{
static async System.Threading.Tasks.Task Main(string[] args)
{
var httpHandler = new HttpClientHandler();
httpHandler.ServerCertificateCustomValidationCallback =
HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;

var channel = GrpcChannel.ForAddress("https://localhost:5001",
new GrpcChannelOptions { HttpHandler = httpHandler });
var client = new Greeter.GreeterClient(channel);
var response = await client.SayHelloAsync(new HelloRequest { Name = "lingme" });
Console.WriteLine(response.Message);
}
}
}

如果出现某个类型缺失引用,我们可以使用 VS 的智能快捷键

Alt + Enter

实现快速 Nuget 安装和引用,上面的代码过于简单我就不一一解释了,我们运行起我们的服务端和客户端,就会看到如下结果,我们的教程至此结束,一个简单的 grpc 服务和客户端就这样实现了,大家可以举一反三应用到自己的实际项目中,比如我正在做的 IM 聊天软件项目。

评论