前言

最近在项目中实装应用了gRPC技术,本着能把技术描述出来给别人能看的懂的思想及作为自己学习笔记的心态编写了此文。因为在实际项目中是webApi接口和gRPC接口使用在同一项目服务中,所以本文的例子也是建立在webApi项目而非控制台项目中。

1、gRPC介绍

gRPC 是Google发起的一个开源远程过程调用 系统。该系统基于HTTP/2 协议传输,使用Protocol Buffers 作为接口描述语言。 其他功能: 认证 双向流 流控制 超时 最常见的应用场景是: 微服务框架下,多种语言服务之间的高效交互。 将手机服务、浏览器连接至后台 产生高效的客户端库-- 维基百科

微软官网介绍:

gRPC是一种与语言无关的高性能远程过程调用 (RPC) 框架。

gRPC 的主要好处是:

现代、高性能、轻量级的 RPC 框架。

合约优先的 API 开发,默认使用 Protocol Buffers,允许语言无关的实现。

可用于多种语言的工具来生成强类型服务器和客户端。

支持客户端、服务器和双向流式调用。

通过 Protobuf 二进制序列化减少网络使用。

这些优势使 gRPC 非常适合:

效率至关重要的轻量级微服务。

需要多种语言进行开发的多语言系统。

需要处理流请求或响应的点对点实时服务。

2、gRPC服务端开发

服务端的接口以传入一个组织id作为入参,返回该组织用户基本信息为例子
* 首先创建一个webApi项目作为服务端
![](https://img2022.cnblogs.com/blog/855221/202207/855221-20220709130715436-144401422.png)

  • 程序包管理器控制台添加 Grpc.AspNetCore nuget包引用

    Install-Package Grpc.AspNetCore -Version 2.47.0*

  • 新建一个Grpc及Proto文件夹分别放置 gRPC服务和proto文件(方便管理)

  • 在proto文件夹下新建一个 user.proto 文件(vs 文件模板没有该后缀名文件,直接新建任意文件改文件名即可),在 user.proto文件中定义gRPC服务方法、入参及返回值

点击查看代码

syntax = "proto3"; option csharp_namespace = "GrpcUser"; package UserApi; service User {
rpc GetUserByOrganizationId(OrganizationUserRequest) returns (OrganizationUserRequestResponse) {}
} message OrganizationUserRequest {
string organizationid = 1;
} message OrganizationUserRequestResponse {
string organizationid = 1;
repeated OrganizationUserItemResponse items = 2;
} message OrganizationUserItemResponse {
string id = 1;
string name =2;
int32 sex = 3;
}
  • 右键编辑项目文件,增加一个节点,并把 user.proto 文件包含进去

点击查看代码
<Project Sdk="Microsoft.NET.Sdk.Web">

	<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup> <ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.47.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup> <ItemGroup>
<Folder Include="Grpc\" />
</ItemGroup> <ItemGroup>
<Protobuf Include="Proto\user.proto" GrpcServices="Server" Generator="MSBuild:Compile"/>
</ItemGroup>
</Project>
  • Grpc文件夹下新建类 UserService,并继承 User.UserBase 并重写 GetUserByOrganizationId 方法实现并接口业务
点击查看代码

using Grpc.Core;
using GrpcUser; namespace gRPCServer.Grpc
{
public class UserService : User.UserBase
{
public override Task<OrganizationUserResponse> GetUserByOrganizationId(OrganizationUserRequest request, ServerCallContext context)
{ /*******此处实际业务从持久层获取数据**********/
var organizationUser = new OrganizationUser(request.Organizationid);
organizationUser.Items = GetUserInfos(); return Task.FromResult(MapToResponse(organizationUser));
} private List<UserInfo> GetUserInfos()
{
var userInfos = new List<UserInfo>();
userInfos.Add(new UserInfo
{
Id = 1,
Name = "用户1",
Sex = 0
}); userInfos.Add(new UserInfo
{
Id = 2,
Name = "用户2",
Sex = 1
}); return userInfos;
} private OrganizationUserResponse MapToResponse(OrganizationUser organizationUser)
{
var response = new OrganizationUserResponse()
{
Organizationid = organizationUser.OrganizationId
}; organizationUser.Items.ForEach(item => response.Items.Add(new OrganizationUserItemResponse
{
Id = item.Id,
Name = item.Name,
Sex = item.Sex
})); return response;
}
} public class OrganizationUser
{
public string? OrganizationId { get; set; }
public List<UserInfo> Items { get; set; }
public OrganizationUser(string organizationId)
{
OrganizationId = organizationId;
}
} public class UserInfo
{
public int Id { get; set; }
public string Name { get; set; }
public int Sex { get; set; }
}
}
  • 在Program 文件中启用grpc中间件并映射我们写好的服务


//启用grpc
builder.Services.AddGrpc(); //映射grpc服务
app.MapGrpcService<UserService>();
  • 因为我们的项目是跑在webApi的项目中,所以还要配置内核去监听另一个端口才能接收并处理gRPC的请求
builder.WebHost.ConfigureKestrel(
options =>
{
//webApi监听端口
options.Listen(System.Net.IPAddress.Any, 5157, listenOptions =>
{
listenOptions.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http1AndHttp2;
}); //grpc监听端口
options.Listen(System.Net.IPAddress.Any, 5158, listenOptions =>
{
listenOptions.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http2;
});
}
);
  • 完整的Program
点击查看代码
using gRPCServer.Grpc;

var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(
options =>
{
//webApi监听端口
options.Listen(System.Net.IPAddress.Any, 5157, listenOptions =>
{
listenOptions.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http1AndHttp2;
}); //grpc监听端口
options.Listen(System.Net.IPAddress.Any, 5158, listenOptions =>
{
listenOptions.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http2;
});
}
); // Add services to the container. builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(); //启用grpc
builder.Services.AddGrpc(); var app = builder.Build(); // Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
} //映射grpc服务
app.MapGrpcService<UserService>(); app.UseAuthorization(); app.MapControllers(); app.Run();
  • 这样,我们的gRPC的服务端就搞定了,完整的项目结构就变成这样了

3、gRPC客户端开发

客户端项目我们也是新建一个webApi项目,并在webapi接口中调用我们的gRPC服务接口获取数据并以json格式输出
* 首先新建一个webApi项目

  • 程序包管理器控制台添加 Grpc.AspNetCore nuget包引用

    Install-Package Grpc.AspNetCore -Version 2.47.0
  • 新建文件夹proto,并将 gRPCServer项目的 user.proto 文件拷贝过来
  • 右键编辑项目文件,增加一个节点,并把 user.proto 文件包含进去(节点Server属性要设置为 Client)

<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup> <ItemGroup>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup> <ItemGroup>
<Folder Include="Controllers\" />
</ItemGroup> <ItemGroup>
<Protobuf Include="Proto\user.proto" GrpcServices="Client" Generator="MSBuild:Compile"/>
</ItemGroup>
</Project>
  • 在Program文件中注入 Grpc客户端
//注入grpc客户端
builder.Services.AddGrpcClient<GrpcUser.User.UserClient>(
options =>
{
options.Address = new Uri("http://localhost:5158"); //grpcServer项目配置的grpc服务监听端口
});
  • 新建控制器 UserController 调用 grpcClient获取数据
using Microsoft.AspNetCore.Mvc;
using GrpcUser; namespace gRPCClient.Controllers
{
[ApiController]
[Route("[controller]")]
public class UserController : ControllerBase
{
private User.UserClient _userClient;
public UserController(User.UserClient userClient)
{
_userClient = userClient;
} /// <summary>
/// 获取用户
/// </summary>
/// <param name="organizationId"></param>
/// <returns></returns>
[HttpGet] public async Task<OrganizationUserResponse> GetUser(string organizationId)
{
var user = await _userClient.GetUserByOrganizationIdAsync(new OrganizationUserRequest { Organizationid = organizationId }); return user;
}
}
}
  • 先启动 grpcSever项目,然后再启动 client项目,在swagger页面调用 GetUser方法即可获取到grpc接口返回数据,Grpc服务于客户端调用就搭建好了



  • 完整项目结构

4、gRPC服务端接口本地调试

grpcServer的接口服务不能像webApi一样直接启动就能进行调试,需要借助一些第三方中间件进行协助测试。我这边使用的是grpcui 进行对本地grpc服务接口的开发调试,下面是grpcui的安装及使用步骤

  • grpcui是Go语言编写的,所以第一步我们先要进行Go环境的搭建。

  • 打开Go官网 ,下载并安装

  • 安装完成,以管理员身份打开PowerShell,并修改Go环境变量

    go env -w GO111MODULE=on

  • 因为Go 包源在外网,所以我们要设置一些代理,方便安装

    go env -w GOPROXY=https://goproxy.cn,direct

  • 安装grpcui

    go install github.com/fullstorydev/grpcui/cmd/grpcui@latest

  • 安装完成即可使用命令测试是否安装成功

    grpcui --help

  • 安装完调试工具还需要修改一些我们的grpcService项目,让项目把grpc服务接口给反射出来,grpcui工具才能获取到相应接口并以webUi的方式进行调试

  • 程序包管理器控制台添加 Grpc.AspNetCore.Server.Reflection nuget包引用

    Install-Package Grpc.AspNetCore.Server.Reflection -Version 2.47.0

  • 项目注入grpc服务反射包服务

    builder.Services.AddGrpcReflection();

  • 启用grpc映射

    app.MapGrpcReflectionService();

  • 最终gRPCServer项目的Program 文件配置如下

using gRPCServer.Grpc;

var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(
options =>
{
//webApi监听端口
options.Listen(System.Net.IPAddress.Any, 5157, listenOptions =>
{
listenOptions.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http1AndHttp2;
}); //grpc监听端口
options.Listen(System.Net.IPAddress.Any, 5158, listenOptions =>
{
listenOptions.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http2;
});
}
); // Add services to the container. builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(); //启用grpc
builder.Services.AddGrpc();
//启用grpc反射
builder.Services.AddGrpcReflection(); var app = builder.Build(); // Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
} //映射grpc服务
app.MapGrpcService<UserService>(); //映射grpc反射服务
app.MapGrpcReflectionService(); app.UseAuthorization(); app.MapControllers(); app.Run();
  • 启动gRPC项目

  • PowerShell 执行命令 grpcui -plaintext {grpc服务的ip端口地址} 即可开启webUi界面调试grpc接口

  • 启动的WebUI调试页面

在此页面我们就可以像使用Postman调试webApi一样调试我们的grpc接口了

参考资料

微软gRPC使用教程:https://docs.microsoft.com/en-us/aspnet/core/grpc/?view=aspnetcore-6.0

grpcui测试grpc服务教程:https://docs.microsoft.com/en-us/aspnet/core/grpc/test-tools?view=aspnetcore-6.0

grpcui项目教程:https://github.com/fullstorydev/grpcui

.NetCore|.Net6 gRPC服务开发及本地调试的更多相关文章

  1. 微信公众号开发 VS2015本地调试

    1.部署一个微信公众号服务在本地IIS: 2.下载一个ngrok 穿网工具,放到部署文件夹根目录: ngrok穿网 在部署路径下打开cmd,输入 ngrok http [端口号] 4.将映射的URL ...

  2. 利用NATAPP隧道解决微信公众号开发之本地调试难题

    一.问题 众所周知,微信公众号开发需要公网的有效域名和80端口,本机当然互联网是访问不了的.那么我们难道去一个公网的服务器去开发吗?那样是不是太土了. 答案当然是,NO 当然我们在做微信支付的时候,有 ...

  3. ballerina 学习二十八 快速grpc 服务开发

    ballerina 的grpc 开发模型,对于开发者来说简单了好多,不是schema first 的方式,而是我们 只要编写简单的ballerina service 就可以了,proto 文件是自动帮 ...

  4. C# Windows Service服务的创建和调试

    前言 关于Windows服务创建和调试的文章在网络上的很多文章里面都有,直接拿过来贴在这里也不过仅仅是个记录,不会让人加深印象.所以本着能够更深刻了解服务项目的创建和调试过程及方法的目的,有了这篇记录 ...

  5. chrome本地调试跨域问题

    1.关闭chrome浏览器(全部) 我们可以通过使用chrome命令行启动参数来改变chrome浏览器的设置,具体的启动参数说明参考这篇介绍.https://code.google.com/p/xia ...

  6. 五分钟给你的 gRPC服务 加上 HTTP 接口

    gRPC 服务要加 HTTP 接口? go-zero 给大家带来极简的 RESTful 和 gRPC 服务开发体验的同时,社区又给我们提出了新的期望: 我想只写一次代码 既要 gRPC 接口 也要 H ...

  7. 【.NET6】gRPC服务端和客户端开发案例,以及minimal API服务、gRPC服务和传统webapi服务的访问效率大对决

    前言:随着.Net6的发布,Minimal API成了当下受人追捧的角儿.而这之前,程序之间通信效率的王者也许可以算得上是gRPC了.那么以下咱们先通过开发一个gRPC服务的教程,然后顺势而为,再接着 ...

  8. Adnc如何本地调试 - 一个轻量级的.Net Core微服务开发框架

    前言     Adnc是一个轻量级的.Net Core微服务开发框架,同样适用于单体架构系统的开发.     如果只是想本地调试,只需要安装必备软件,必备软件除开发工具外,其它软件建议大家都使用`do ...

  9. 通过Dapr实现一个简单的基于.net的微服务电商系统(十四)——开发环境容器调试小技巧

    之前有很多同学提到如何做容器调试,特别是k8s环境下的容器调试,今天就讲讲我是如何调试的.大家都知道在vs自带的创建项目模板里勾选docker即可通过F5启动docker容器调试.但是对于启动在k8s ...

随机推荐

  1. linux搭建ntp时间同步服务

    1.NTP简介 NTP(Network Time Protocol,网络时间协议)用来使计算机时间同步的一种协议.它可以使计算机对其服务器或时钟源做同步化,它可以提供高精准度的时间校正(LAN上与标准 ...

  2. Linux获取本机公网IP,调整双节点主从服务的RPC调用逻辑

    简单记录一次双节点的之间的服务调用叭 ~ 现有: 服务A的双节点A1.A2 服务B的双节点B1.B2 服务A 和服务B 通过 Netty 实现 RPC 通信,可能会导致比较玄学的问题.如图: 要做到 ...

  3. 领域驱动模型DDD(三)——使用Saga管理事务

    前言 虽然一直说想写一篇关于Saga模式,在多次尝试后不得不承认这玩意儿的仿制代码真不是我一个菜鸟就能完成的,所以还是妥协般地引用现成的Eventuate Tram Saga框架(虽然我对它一直很反感 ...

  4. IDEA编译项目后,target目录下的jsp文件不更新

    tomcat目录说明 先来看一下tomcat的目录: |-bin |-conf |-lib |-logs |-temp |-webapps |-work tomcat 的核心是servlet容器,叫 ...

  5. react 可拖拽改变位置和大小的弹窗

    一 目标 最近,项目上需要一个可以弹出一个可以移动位置和改变大小的窗口,来显示一下对当前页面的一个辅助内容 二 思路 1.之前写过一个antd modal的可移动弹窗但是毕竟不如自己写的更定制化,比如 ...

  6. 攻防世界-MISC:János-the-Ripper

    这是攻防世界MISC高手进阶区的题目: 点击下载附件一,解压后得到一个没有后缀的文件,老规矩用010editor打开,发现存在一个flag.txt文件 用foremost分离一下: flag.txt被 ...

  7. Bootstrap Blazor 模板使用(一)Layout 组件

    原文链接:https://www.cnblogs.com/ysmc/p/16197223.html BootstrapBlazor 官网地址:https://www.blazor.zone Boots ...

  8. 附011.常见Linux镜像站点大全

    开源系统镜像站点 国内Mirrors站点 企业类站点 阿里巴巴开源Mirrors站点:https://developer.aliyun.com/mirror/ 腾讯开源Mirrors站点:https: ...

  9. 基本命令学习 -(3)Linux压缩和解压缩命令汇总

    关注「开源Linux」,选择"设为星标" 回复「学习」,有我为您特别筛选的学习资料~ 前言 Linux下的压缩和解压缩工具比较多,有时经常记不住,这里给大家汇总一下,方便大家查阅. ...

  10. svelte组件:svelte3.x自定义美化虚拟滚动条组件svelte-scrollbar

    基于svelte3.0自定义pc端虚拟滚动条组件svelteScrollbar. svelte-scrollbar:运用svelte3.x创建的桌面pc版自定义美化滚动条组件.支持是否原生滚动条.自动 ...