前言

最近在项目中实装应用了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. Maven基础学习笔记

    Maven基础学习笔记 下载链接 官网:https://maven.apache.org/ 所有版本:https://archive.apache.org/dist/maven/maven-3/ 阿里 ...

  2. tuandui last

    组长博客链接### 组长博客 参考邹欣老师的问题模板进行总结思考### 设想和目标(2分)#### 1.我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 解决的问题 ...

  3. 干货 | 手把手教你搭建一套OpenStack云平台

    1 前言 今天我们为一位朋友搭建一套OpenStack云平台. 我们使用Kolla部署stein版本的OpenStack云平台. kolla是用于自动化部署OpenStack的一个项目,它基于dock ...

  4. 重新审视C# Span<T>数据结构

    先谈一下我对Span的看法, span是指向任意连续内存空间的类型安全.内存安全的视图. Span和Memory都是包装了可以在pipeline上使用的结构化数据的内存缓冲器,他们被设计用于在pipe ...

  5. 【Pandas vs SQL】数据分析代码逐行比对,孰优孰劣?

    在数据分析领域,pandas是python数据分析基础工具,SQL是数据库最常用分析语言.二者有相通的地方,也有很大的语法不同,做起数据分析来,谁将更胜一筹呢? 做过业务开发.跟数据库打交道比较多的小 ...

  6. Go语言学习——函数二 defer语句

    函数 package main import "fmt" // 函数:一段代码的封装 func f1(){ fmt.Println("Hello 中国!") } ...

  7. MongoDB是什么?非关系型数据库的优点?安装使用教程

    哈喽!大家好,我是小奇,一位热爱分享的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 书接上回,由于球姐都有孩子了, ...

  8. 斯坦福NLP课程 | 第12讲 - NLP子词模型

    作者:韩信子@ShowMeAI,路遥@ShowMeAI,奇异果@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/36 本文地址:http://www. ...

  9. Python的.gitignore模板

    参考:https://github.com/github/gitignore Python的.gitignore模板,记录一下方便查询 # Byte-compiled / optimized / DL ...

  10. 119_Power Pivot 长尾明细显示为【其他】

    博客:www.jiaopengzi.com 焦棚子的文章目录 请点击下载附件 一.背景 最近比较忙,太久不没有更新文章,确实没有好的素材,就写一个吧. 在关于产品数据分析的时候,我们经常关注的是主要的 ...