本文提供一个最简单的grpc demo,来模拟一个本地应用使用grpc的方式去调用一个远程的服务
- 首先创建一个grpc项目来模拟远程服务
- 再创建一个项目来调用服务
- 如果需要在web api项目而不是控制台程序中调用远程服务
先打开vs,新建一个ASP.NET Core gRPC项目(直接搜索grpc就好了)
项目创建好后
重点关注Protos文件夹和Services文件夹
Protos文件夹用于存放.proto文件。(.proto文件我理解为是对远程服务的一种描述,例如服务所在的命名空间是什么,服务提供了哪些方法,服务的出参入参是什么类型的这样的信息)
可以双击打开greet.proto文件看一下
syntax = "proto3";
option csharp_namespace = "GrpcServiceDemo";
package greet;
// The greeting service definition.
service Greeter {
// Sends a greeting
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;
}
可以看到
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply);
}
这就是描述了服务是有一个SayHello方法,该方法的入参是HelloRequest类型的,该方法的出参是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;
}
就是关于出入参类型的描述,可以看到入参HelloRequest类型有一个string类型的name属性,出参HelloReply类型有一个string类型的message属性
再来看Services文件夹,该文件夹用于存放服务类,在其中定义具体的逻辑
我们可以查看一下GreeterService.cs文件代码
using Grpc.Core;
using GrpcServiceDemo;
namespace GrpcServiceDemo.Services
{
public class GreeterService : Greeter.GreeterBase
{
private readonly ILogger _logger;
public GreeterService(ILogger logger)
{
_logger = logger;
}
public override Task SayHello(HelloRequest request, ServerCallContext context)
{
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
});
}
}
}
可以看到,GreeterService实现了Greeter.GreeterBase,重写了SayHello方法。(其中Greeter.GreeterBase是根据.proto文件自动生成的,生成的文件在objDebugnet6.0Protos目录下,如果没有的话生成一下解决方案)
至此,服务就创建好了。(实际上,我们仅仅是创建一个grpc项目就OK了)
打开vs,新建一个控制台应用
导入Nuget包
Install-Package Google.Protobuf Install-Package Grpc.Net.Client Install-Package Grpc.Tools
然后将我们刚刚创建的那个服务项目的Protos文件夹复制进来
双击项目打开.csproj文件,添加
修改Program.cs代码
using Grpc.Net.Client;
using GrpcServiceDemo;
using System;
using static GrpcServiceDemo.Greeter;
namespace GrpcClientDemo
{
internal class Program
{
static void Main(string[] args)
{
#region 创建客户端
GrpcChannel grpcChannel = GrpcChannel.ForAddress("https://localhost:5001"); //(注意确保服务的地址正确)
GreeterClient greeterClient = new GreeterClient(grpcChannel);
#endregion
#region 调用服务
HelloReply helloReply = greeterClient.SayHello(new HelloRequest()
{
Name = "张三"
});
#endregion
Console.WriteLine(helloReply.Message);
}
}
}
现在就可以进行测试了
运行服务端,服务端成功启动后,再运行客户端来尝试调用服务,如果出现正确输出,则证明grpc调用服务成功了
可以发现,使用grpc,客户端调用server端提供的接口就像是调用本地的函数一样
如果需要在web api项目而不是控制台程序中调用远程服务新建一个asp.net core web api项目
导包
Install-Package Google.Protobuf Install-Package Grpc.Net.Client Install-Package Grpc.Net.ClientFactory Install-Package Grpc.Tools
将服务端的Protos文件夹复制进web api项目中
添加引用
注册GreeterClient进容器
services.AddGrpcClient(options => { options.Address = new Uri("https://localhost:5001");//(注意确保服务的地址正确) });
Controller中写一个Action,在此Action中注入服务进行测试
[HttpGet]
public object Test([FromServices] GreeterClient client)
{
HelloReply helloReply = client.SayHello(new GrpcServiceDemo.HelloRequest()
{
Name = "李四"
});
return helloReply.Message;
}
启动Grpc服务项目和web api项目
访问测试的Action发现返回了数据,远程调用成功



