天天看点

ASP.NET core 3.0使用grpc

在开始之前,善意提醒:计算机名称不要是中文,文件夹也一样

服务端:

第一步:

使用NuGet下载三个包

Microsoft.EntityFrameworkCore.SqlServer:Sql Server数据库EF提供程序
Microsoft.EntityFrameworkCore.Design:设计时EF共享库
 Microsoft.EntityFrameworkCore.Tools:EF的NuGet包管理器命令工具
           

注意:

到这一步,有的人会出现黄色的感叹号,不要慌,看看你的计算机是不是中文名称,查看方法:cmd=>hostname。

再看看文件夹是不是也有中文,如果有的话,需要解决以上问题,如果要改计算机的名称时记得备份。

ASP.NET core 3.0使用grpc

第二步:

在NuGet管理器控制输入以下指令生成实体类和上下文类

语句:

Scaffold-DbContext ‘连接字符串’ 数据提供程序名称 -OutputDir 结果输出文件夹 -Context 数据上下文名
–DataAnnotations
           

例如:

Scaffold-DbContext ‘Data Source=.\SQL2017;Initial Catalog=ShoppingDB;
Integrated Security=True;’ Microsoft.EntityFrameworkCore.SqlServer
-OutputDir Models -Context ShopContext
           

第三步:

右键项目 — 新建项 — ASP.NET CORE 常规下选择 协议区缓冲文件 — 取名xxx.proto(这里举例取名为:shop.proto)

第四步:

定义protobuf接口文件

syntax = "proto3";

option csharp_namespace = "GrpcService";

package product;

import "google/protobuf/empty.proto";

service ProductManager{
    rpc GetProductByID(ProductRequest) returns (ProductResponse);
    rpc GetProductList(google.protobuf.Empty)  returns (ProductListResponse);
}

message ProductInfo{
   int32 ProductId=1;
   string ProductName=2 ;
   int32 CategoryId=3;
   double ProductPrice=4;
   int32 Stock=5;
   string ProductDesc =6;
   string ProductImg =7;
}

message ProductRequest{
    int32 id=1;
}

message ProductResponse{
    ProductInfo product=1;
}

message ProductListResponse{
    repeated ProductInfo product=1;
}
           

注意:在这个文件内不要写任何中文,否则会报错。

第五步:

右键添加服务引用 注意是【服务端】,然后运行检查protobuf文件是否书写正确

ASP.NET core 3.0使用grpc
ASP.NET core 3.0使用grpc
ASP.NET core 3.0使用grpc
ASP.NET core 3.0使用grpc

第六步:

在appsettings.json文件中添加连接字符串json

{
  "ConnectionStrings": {
    "ShopConStr": "Data Source=.;Initial Catalog=ShoppingDB; Integrated Security=True;"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http2"
    }
  }
}
           

第七步:

在 startup类完成上下文类的注册和grpc服务的映射

①注册下下文类注册

using GrpcService.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using GrpcService.Services;

        public IConfiguration Configuration { get; set; }

        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }
        public void ConfigureServices(IServiceCollection services)
        {
            // 注册上下文类
            services.AddDbContext<ShopContext>(options=> {
                options.UseSqlServer(Configuration.GetConnectionString("ShopConStr"));
            });
            services.AddGrpc();
        }
           

②Grpc服务注册:这一步非常重要,别落下了

ASP.NET core 3.0使用grpc

代码如下:

endpoints.MapGrpcService();//添加URL与grpc服务的映射关系

第八步:

在Services文件夹新建ShopService类,完成方法的实现

public class ShopService:ProductManager.ProductManagerBase   // 对应的是protobuf文件的服务名称
    {
        private readonly ShopContext _context;
        private readonly ILogger<ShopService> _logger;
        public ShopService(ShopContext context,ILogger<ShopService> logger)  // 依赖注入
        {
            _context = context;
            _logger = logger;
        }

        public override Task<ProductResponse> GetProductByID(ProductRequest request, ServerCallContext context)
        {
            // 定义输出参数
            var res = new ProductResponse();
            // 书写查询语句
            var pro = _context.Products.Where(p=>p.ProductId==request.Id).Select(p => new ProductInfo
            {
                ProductId = p.ProductId,
                ProductDesc = p.ProductDesc,
                ProductImg = p.ProductImg,
                ProductName = p.ProductName
            }
            ).FirstOrDefault();
            _logger.LogInformation("已经开始读取数据库的数据");
            // 将查询结果赋值给输出参数
            res.Product = pro;
            // 返回结果
            return Task.FromResult(res);
        }

        public override Task<ProductListResponse> GetProductList(Empty request, ServerCallContext context)
        {
            // 定义输出参数
            var res = new ProductListResponse();
            // 书写查询语句
            var list = _context.Products.Select(p=>new ProductInfo
            {
                ProductId=p.ProductId,
                ProductDesc=p.ProductDesc,
                ProductImg=p.ProductImg,
                ProductName=p.ProductName
            }
            ).ToArray();
            _logger.LogInformation("已经开始读取数据库的数据");
            _logger.LogInformation($"list有{list.Length}条");
            // 将查询结果赋值给输出参数
            res.Product.Add(list);
            // 返回结果
            return Task.FromResult(res);
        }
    }
           

以上是服务器端的配置,下面是客户端

客户端

创建GRPC客户端:

具体步骤:

1.创建项目(根据需求来,我创建的是MVC的项目)

2.添加grpc服务,注意是客户端,和之前添加服务端方法一致

3.在控制器index()操作方法完成以下代码。

注意命名空间的引用,先引用using Grpc.Net.Client

【注意】 protobuf文件命名空间与服务类文件命名空间一致

//查集合
public IActionResult Index()
        {
            // 创建服务器的信道
            var channel = GrpcChannel.ForAddress("https://localhost:5001");
            // 创建客户端
            GrpcService.ProductManager.ProductManagerClient client = new GrpcService.ProductManager.ProductManagerClient(channel);
            // 调用相应的方法
            var list = client.GetProductList(new Google.Protobuf.WellKnownTypes.Empty());
            // 模型传值
            return View(list.Product.ToList());
        }
//查对象
public IActionResult Index()
        {
            // 创建服务器的信道
            var channel = GrpcChannel.ForAddress("https://localhost:5001");
            // 创建客户端
            GrpcService.ProductManager.ProductManagerClient client = new GrpcService.ProductManager.ProductManagerClient(channel);
            // 调用相应的方法
           var pro = client.GetProductByID(new GrpcService.ProductRequest { Id=1023});//id值看你数据库的id
            // 模型传值
            return View(pro.Product);
        }
           

下面就自己写视图显示数据了。

如需引用,请备注出处哟!!!!!!!