.NET Core(.NET6)中gRPC使用实践

2022-04-18 19:35:34
目录
一、简介二、创建gRPC服务端1.创建gRPC项目2.编写自己的服务三、创建gRPC客户端1.创建客户端项目2.grPC服务https的调用3.gRPC内网http调用4.IOC注入的方式调用gRPC四、webapi中加入gRPC

一、简介

简单解析一下gRPC,gRPC 是一个由Google开源的,跨语言的,高性能的远程过程调用(RPC)框架。

特点:

跨语言内容protobuf格式(比json体积小),网络传输快使用HTTP/2进行传输

适合高性能轻量的微服务,一般对外的接口用restful api,内部服务的调用用gRPC。gRPC是一个分布式服务框架,和以前的WebService,WCF类似。

二、创建gRPC服务端

1.创建gRPC项目

新建一个gRPC模板的项目

.NETCore(.NET6)中gRPC使用实践

.NETCore(.NET6)中gRPC使用实践

.NETCore(.NET6)中gRPC使用实践

特别的地方就这里4点。

1.基于http2来通信。

2.proto协议文件,gr易采站长站eet.proto是项目默认给我们的一个hello world的示例。它会根据协议自动生成需要的类。

.NETCore(.NET6)中gRPC使用实践

3.服务类,Greeter.GreeterBase来自于2中的proto文件自动生成的类,生成的类在objDebugnet6.0Protos 目录下。

.NETCore(.NET6)中gRPC使用实践

自动生成的类:

.NETCore(.NET6)中gRPC使用实践

4.Program.cs添加了gRPC服务,和把GreeterService注册到管道中。

2.编写自己的服务

怎么样写自己的调用服务呢?

1.创建proto文件

参照上面的示例创建自己的Proto文件

.NETCore(.NET6)中gRPC使用实践

代码:

syntax = "proto3";option csharp_namespace = "GrpcDemo.Service";package order;// 订单服务定义service Order {  // 创建订单  rpc CreateOrder (CreateRequest) returns (CreateResult);  //查询订单  rpc QueryOrder (QueryRequest) returns (QueryResult);}//创建订单请求参数message CreateRequest {  string orderNo = 1;  string orderName=2;  double price=3;}//创建订单返回结果message CreateResult {  bool result = 1;  string message=2;}//查询订单请求参数message QueryRequest{    int id=1;}//查询订单返回结果message QueryResult{    int id=1;    string orderNo=2;    string orderName=3;    double price=4;}

生成一下就能看到对应的类已经生成了。

.NETCore(.NET6)中gRPC使用实践

2.实现定义的服务

创建OrderService.cs

public class OrderService:Order.OrderBase    {        private readonly ILogger<GreeterService> _logger;        public OrderService(ILogger<GreeterService> logger)        {            _logger = logger;        }        /// <summary>        /// 创建订单        /// </summary>        /// <param name="request"></param>        /// <param name="context"></param>        /// <returns></returns>        public override Task<CreateResult> CreateOrder(CreateRequest request, ServerCallContext context)        {            //报存数据库 todo            return Task.FromResult(new CreateResult            {                Result=true,                Message="订单创建成功"            });        }        /// <summary>        /// 查询订单        /// </summary>        /// <param name="request"></param>        /// <param name="context"></param>        /// <returns></returns>        public override Task<QueryResult> QueryOrder(QueryRequest request, ServerCallContext context)        {            //查询数据库 //todo            return Task.FromResult(new QueryResult            {                OrderInfo=new OrderInfo                {                    Id = request.Id,                    OrderNo = DateTime.Now.ToString("yyyyMMddHHmmss"),                    OrderName = "冰箱",                    Price = 1288                }            });        }    }

继承的Order.OrderBase 是上面的proto文件生成的,然后实现了proto里面定义的两个服务。

然后在program.cs里面把服务注入管道。

.NETCore(.NET6)中gRPC使用实践

到这里服务端就完成了,就可以启动服务端了。

.NETCore(.NET6)中gRPC使用实践

浏览器访问不了,要通过gRPC客户端才能访问,下面就建一个gRPC客户端。

三、创建gRPC客户端

1.创建客户端项目

1.1、这里创建一个控制台程序。

1.2、然后添加Nuget包

Google.ProtobufGrpc.Net.ClientGrpc.ToolsGrpc.Net.clientFactory

1.3、把服务端的proto文件拷贝过来

.NETCore(.NET6)中gRPC使用实践

1.4、编辑项目文件,把proto里面的内容替换掉,默认是服务端的配置

.NETCore(.NET6)中gRPC使用实践

  <Protobuf Include="Protosgreet.proto" GrpcServices="Client" />      <Protobuf Include="Protosorder.proto" GrpcServices="Client" />

生成的时候,客户端也生成了对应proto的类

.NETCore(.NET6)中gRPC使用实践

2.grPC服务https的调用

因为服务端提供了http和https的端口,这里先调用https的

创建GrpcRequestTest.cs类

/// <summary>    /// gRPC请求测试    /// </summary>    public class GrpcRequestTest    {        public void CreateOrder()        {            //常规使用,https            string url = "https://localhost:7246";            using(var channel=GrpcChannel.ForAddress(url))            {                var client = new Order.OrderClient(channel);                var reply = client.CreateOrder(new CreateRequest()                {                    OrderNo = DateTime.Now.ToString("yyyMMddHHmmss"),                    OrderName = "冰箱22款",                    Price = 1688                });                Console.WriteLine($"结果:{reply.Result},message:{reply.Message}");            }            Console.ReadKey();        }    }

结果:

.NETCore(.NET6)中gRPC使用实践

3.gRPC内网http调用

public void CreateOrder()        {             //使用http            AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);            string url = "http://localhost:5246";            using(var channel=GrpcChannel.ForAddress(url))            {                var client = new Order.OrderClient(channel);                var reply = client.CreateOrder(new CreateRequest()                {                    OrderNo = DateTime.Now.ToString("yyyMMddHHmmss"),                    OrderName = "冰箱22款",                    Price = 1688                });                Console.WriteLine($"结果:{reply.Result},message:{reply.Message}"); www.easck.com           }            Console.ReadKey();        }

比起https,前面多了一行。结果:

.NETCore(.NET6)中gRPC使用实践

4.IOC注入的方式调用gRPC

4.1、program.cs里面注入gRPCClient

// See https://aka.ms/new-console-template for more informationusing GrpcDemo.Client;using GrpcDemo.Service;using Microsoft.Extensions.DependencyInjection;Console.WriteLine("Hello, World!");IServiceCollection services = new ServiceCollection();services.AddTransient<GrpcRequestTest>();#region gRPC Client注册AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);services.AddGrpcClient<Order.OrderClient>(options =>{    options.Address = new Uri("http://localhost:5246");}).ConfigureChannel(grpcOptions =>{    //可以完成各种配置,比如token});#endregion//构建容器IServiceProvider serviceProvider = services.BuildServiceProvider();//解析grpc请求测试var grpcRequestTest = serviceProvider.GetService<GrpcRequestTest>();//执行grpcRequestTest.CreateOrder();

grpcRequestTest里代码:

/// <summary>    /// gRPC请求测试    /// </summary>    public class GrpcRequestTest    {        private Order.OrderClient _orderClient;        public GrpcRequestTest(Order.OrderClient orderClient)        {            _orderClient = orderClient;        }        public void CreateOrder()        {            var reply = _orderClient.CreateOrder(new CreateRequest()            {                OrderNo = DateTime.Now.ToString("yyyMMddHHmmss"),                OrderName = "冰箱22款",                Price = 1688            });            Console.WriteLine($"结果:{reply.Result},message:{reply.Message}");            Console.ReadKey();        }    }

结果:

.NETCore(.NET6)中gRPC使用实践

四、webapi中加入gRPC

通常我们的服务有对外提供对外接口,又要对内提供gRPC服务,那怎么做呢,下面在webapi中加入gRPC服务

1.创建asp.net core mvc项目

2.安装nuget包

Grpc.AspNetCore

3.添加protebuf文件

把上面的proto文件复制过来

.NETCore(.NET6)中gRPC使用实践

4.添加Service

.NETCore(.NET6)中gRPC使用实践

public class OrderService : Order.OrderBase    {        private readonly ILogger<OrderService> _logger;        public OrderService(ILogger<OrderService> logger)        {            _logger = logger;        }        /// <summary>        /// 创建订单        /// </summary>        /// <param name="request"></param>        /// <param name="context"></param>        /// <returns></returns>        public override Task<CreateResult> CreateOrder(CreateRequest request, ServerCallContext context)        {            //报存数据库 todo            return Task.FromResult(new CreateResult            {                Result = true,                Message = "订单创建成功"            });        }        /// <summary>        /// 查询订单        /// </summary>        /// <param name="request"></param>        /// <param name="context"></param>        /// <returns></returns>        public override Task<QueryResult> QueryOrder(QueryRequest request, ServerCallContext context)        {            //查询数据库 //todo            return Task.FromResult(new QueryResult            {                OrderInfo = new OrderInfo                {                    Id = request.Id,                    OrderNo = DateTime.Now.ToString("yyyyMMddHHmmss"),                    OrderName = "冰箱",                    Price = 1288                }            });        }    }

5.注册gRPC服务

在Program.cs文件中

.NETCore(.NET6)中gRPC使用实践

到这里,就把gRPC加入到webapi里面了。

6.验证

启动asp.net core mvc程序

.NETCore(.NET6)中gRPC使用实践

浏览器能访问,证明restful api是没问题的。

然后再用上面的客户端访问一下gRPC的服务。

.NETCore(.NET6)中gRPC使用实践

结果:

.NETCore(.NET6)中gRPC使用实践

这样就成功对外提供api接口和对内提供gRPC服务了。

源码地址:https://github.com/weixiaolong325/GrpcDemo.Service