gRPC是什么
gRPC是可以在任何环境中运行的现代开源高性能RPC框架。它可以通过可插拔的支持来有效地连接数据中心内和跨数据中心的服务,以实现负载平衡,跟踪,运行状况检查和身份验证。它也适用于分布式计算的最后一英里,以将设备,移动应用程序和浏览器连接到后端服务。

proto文件
用于定义gRPC服务和消息的协定;服务端和客户端共享proto文件。

使用新模板创建gRPC服务端
.NETcore 3.0创建项目提供了一个新的gRPC模板,可以轻松地使用ASP.NET Core构建gRPC服务。我们按照步骤一步一步创建AA.GrpcService 服务,当然你可以使用命令:dotnet new grpc -o GrpcGreeter

选择gRPC服务项目模板

最终生成的项目

syntax = "proto3";

option csharp_namespace = "AA.GrpcService";

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 = ;
} // The response message containing the greetings.
message HelloReply {
string message = ;
}

GreeterService.cs

 public class GreeterService : Greeter.GreeterBase
{
private readonly ILogger<GreeterService> _logger;
public GreeterService(ILogger<GreeterService> logger)
{
_logger = logger;
} public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
{
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
});
}
}

Startup.cs

public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddGrpc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGrpcService<GreeterService>();
endpoints.MapGet("/", async context =>
{
await context.Response.WriteAsync("Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
});
});
}
}

创建完成之后,自动包含了包的引用、proto文件的创建、services服务的生成,模板项目在后台执行一些操作如

创建一个包含所有gRPC依赖项的ASP.NET Core项目。
创建一个名为的gRPC服务定义文件greet.proto。
根据服务定义文件自动生成所有gRPC存根。
GreeterService.cs根据自动生成的gRPC存根创建gRPC服务。
在Startup.cs中配置gRPC管道映射到GreeterService.cs
运行服务

创建gRPC客户端
下面,我们创建一个控制台应用程序作为客户端调用gRPC服务;

引用gRPC服务,步骤:右键项目添加=》服务引用弹出以下页面;

点击确定

我们看项目结构,他们会自动帮我们处理一下操作:

添加引用包:
 package Grpc.Net.ClientFactory
 package Google.Protobuf
 package Grpc.Tools
Protos 文件(包含greet.proto)自动从AA.GrpcService项目拷贝
自动添加节点

<ItemGroup>
  <Protobuf Include="..\AA.GrpcService\Protos\greet.proto" GrpcServices="Client">
    <Link>Protos\greet.proto</Link>
  </Protobuf>
</ItemGroup>

最后,添加以下代码进行gRPC请求;

  static async System.Threading.Tasks.Task Main(string[] args)
{
var httpClientHandler = new HttpClientHandler();
httpClientHandler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
var httpClient = new HttpClient(httpClientHandler); using var channel = GrpcChannel.ForAddress("https://localhost:5002", new GrpcChannelOptions { HttpClient = httpClient });
var client = new Greeter.GreeterClient(channel);
var response = await client.SayHelloAsync(new HelloRequest { Name = "gRPC" });
Console.WriteLine("Greeting:" + response.Message);
Console.WriteLine("Press a key to exit");
Console.ReadKey();
}

运行结果图:

gRPC与IdentityServer4集成认证授权
Ids4.Server

1.创建一个.net core的webapi

2.nuget引用最新的IdentityServer4的包

<PackageReference Include="IdentityServer4" Version="3.0.1" />
IdentityServer4相关配置,因为是演示所以很简单,生产场景大家根据实际情况配置。

namespace Ids4.Server
{
public class Config
{
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResources.Email(),
};
}
public static IEnumerable<ApiResource> GetApis()
{
return new List<ApiResource>
{
new ApiResource("api", "Demo API")
{
ApiSecrets = { new Secret("secret".Sha256()) }
}
};
}
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client
{
ClientId = "client",
ClientSecrets = { new Secret("secret".Sha256()) }, AllowedGrantTypes = GrantTypes.ClientCredentials,
AllowedScopes = { "api" },
},
};
}
}
}

4. startup.cs 注入服务

services.AddIdentityServer().AddInMemoryApiResources(Config.GetApis())
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryClients(Config.GetClients())
.AddDeveloperSigningCredential(persistKey: false);

5. startup.cs 配置http请求管道

app.UseIdentityServer();

6. 启动服务,使用PostMan进行调试,有返回结果表示服务创建成功

POST /connect/token HTTP/1.1
Host: localhost:
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&client_id=client&client_secret=secret

{
"access_token":"eyJhbGciOiJSUzI1NiIsImtpZCI6IlVYODJRTk9LMWRMR1dDREVUd0xQbkEiLCJ0eXAiOiJhdCtqd3QifQ.eyJuYmYiOjE1NzE4MDU4MzAsImV4cCI6MTU3MTgwOTQzMCwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1MDAwIiwiYXVkIjoiYXBpIiwiY2xpZW50X2lkIjoiY2xpZW50Iiwic2NvcGUiOlsiYXBpIl19.DgJJqIOOSICEGa7S5R4Ok7Pp4hxPjGQP12T4LsDHD5tRsYiV58VcvooglVehKmMbydE7yA7JnYqBR--2Gbss9zjYyq41iY2lP-Y79v70jlVn9TvrpWOIljnWOvLApjFMEXJuV4VHwcXQ7ssgXFrY4Mg_QPaxkJRIKAI8T5cP2W1KvOBkaZqx45o8VpQBfpEyoRjPHQW0wPrM6bBU4IxfTosy874pn2NXVhe2DaPeAcReXYsz5AVtJ4Vt-4fVS1JtcA-aj6OQ__RWYqNK_ApQRFZsuyJKG27EBBrc0byrpw_G1PReRl8hlYnXidGFvijGEawlyEAANXzNNXDk7cSJ2A",
"expires_in":,
"token_type":"Bearer",
"scope":"api"
}

改造Grpc.Server支持IdentityServer4

1. 引入nuget包

<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
2. startup.cs 注入服务,和IdentityServer4一样。

services.AddGrpc(x => x.EnableDetailedErrors = false);
services.AddAuthorization();
services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(options =>
{
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
});

3. startup.cs 配置http请求管道

if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapGrpcService<GreeterService>(); endpoints.MapGet("/", async context =>
{
await context.Response.WriteAsync("Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
});
});

4. 对需要授权的服务打标签[Authorize],可以打在类上也可以打在方法上

[Authorize]
public class GreeterService : Greeter.GreeterBase
{
}

这个时候我们启动Grpc.Client访问Grpc.Server服务

发现报错401。说明此服务需要携带令牌才能访问。

改造Grpc.Client携带令牌访问(需要添加IdentityServer4引用)

 static async System.Threading.Tasks.Task Main(string[] args)
{
var httpClientHandler = new HttpClientHandler();
httpClientHandler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
var httpClient = new HttpClient(httpClientHandler); //获取token可以直接使用HttpClient来获取,这里使用IdentityModel来获取token
var disco = await httpClient.GetDiscoveryDocumentAsync("http://localhost:5000");
if (!disco.IsError)
{
var token = await httpClient.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest()
{
Address = disco.TokenEndpoint,
ClientId = "client",
ClientSecret = "secret"
});
var tokenValue = "Bearer " + token.AccessToken;
var metadata = new Metadata
{
{ "Authorization", tokenValue }
};
var callOptions = new CallOptions(metadata);
////
using var channel = GrpcChannel.ForAddress("https://localhost:5002", new GrpcChannelOptions { HttpClient = httpClient });
var client = new Greeter.GreeterClient(channel);
var response = await client.SayHelloAsync(new HelloRequest { Name = "gRPC" },callOptions);
Console.WriteLine("Greeting:" + response.Message);
} Console.WriteLine("Press a key to exit");
Console.ReadKey();
}

小结: .NETcore 3.0 使得使用gRPC是非常方便集成到项目中,希望这篇文章使你可以了解.NETcore与gRPC结合使用。那gRPC适用于以下场景

微服务– gRPC专为低延迟和高吞吐量通信而设计。 gRPC对于效率至关重要的轻量级微服务非常有用。

点对点实时通信– gRPC对双向流具有出色的支持。 gRPC服务可以实时推送消息而无需轮询。

多种语言环境– gRPC工具支持所有流行的开发语言,因此gRPC是多语言环境的理想选择。

网络受限的环境– gRPC消息使用轻量级消息格式Protobuf进行了序列化。 gRPC消息始终小于等效的JSON消息。

参考:

https://docs.microsoft.com/en-us/aspnet/core/grpc/troubleshoot?view=aspnetcore-3.0

https://docs.microsoft.com/zh-cn/aspnet/core/grpc/?view=aspnetcore-3.0
https://www.grpc.io/
https://developers.google.com/protocol-buffers/docs/proto3
https://www.cnblogs.com/stulzq/p/11581967.html

.Net Core3.0使用gRPC 和IdentityServer4的更多相关文章

  1. .Net Core3.0使用gRPC

    gRPC是什么 gRPC是可以在任何环境中运行的现代开源高性能RPC框架.它可以通过可插拔的支持来有效地连接数据中心内和跨数据中心的服务,以实现负载平衡,跟踪,运行状况检查和身份验证.它也适用于分布式 ...

  2. .net core gRPC与IdentityServer4集成认证授权

    前言 随着.net core3.0的正式发布,gRPC服务被集成到了VS2019.本文主要演示如何对gRPC的服务进行认证授权. 分析 目前.net core使用最广的认证授权组件是基于OAuth2. ...

  3. What?VS2019创建新项目居然没有.NET Core3.0的模板?Bug?

    今天是个值得欢喜的日子,因为VS2019在今天正式发布了.作为微软粉,我已经用了一段时间的VS2019 RC版本了.但是,今天有很多小伙伴在我的<ASP.NET Core 3.0 上的gRPC服 ...

  4. .Net Core 3.0使用Grpc进行远程过程调用

    因为.Net Core3.0已经把Grpc作为一等臣民了,作为爱好新技术的我,当然要尝鲜体验一下了,当然感觉是Grpc作为跨语言的产品做的相当好喽,比起Dubbo这种的,优势和劣势还是比较明显的. 我 ...

  5. 2019年第一天——使用Visual Studio 2019 Preview创建第一个ASP.Net Core3.0的App

    一.前言: 全文翻译自:https://www.talkingdotnet.com/creating-first-asp-net-core-3-0-app-visual-studio-2019/ Vi ...

  6. VS2019没有.net core3.0模板的解决办法

    今天装好了,net core sdk 3.0之后,打开Visual Studio2019后,新建项目时发现尽然没有.net core3.0的模板. 搜了下其他博主的文章,按照文章里做了如下设置:   ...

  7. ASP.NET Core 3.0 使用gRPC

    一.简介 gRPC 是一个由Google开源的,跨语言的,高性能的远程过程调用(RPC)框架. gRPC使客户端和服务端应用程序可以透明地进行通信,并简化了连接系统的构建.它使用HTTP/2作为通信协 ...

  8. asp.net core3.0 mvc 用 autofac

    好久没有写文章了,最近在用.net core3.0,一些开发中问题顺便记录: 1.首先nuget引入 Autofac Autofac.Extensions.DependencyInjection 2. ...

  9. 使用.net core3.0 正式版创建Winform程序

    前阵子一直期待.net core3.0正式版本的出来,以为这个版本出来,Winform程序又迎来一次新生了,不过9.23日出来的马上下载更新VS,创建新的.net core Winform项目,发现并 ...

随机推荐

  1. Android源码分析(十三)----SystemUI下拉状态栏如何添加快捷开关

    一:如何添加快捷开关 源码路径:frameworks/base/packages/SystemUI/res/values/config.xml 添加headset快捷开关,参考如下修改. Index: ...

  2. pycharm Launching unittests with arguments

    在运行程序时出现 但是代码没有错 源代码是: 这是运行时启动了测试 解决方法: File-> Settings -> Tools -> Python Integrated Tools ...

  3. 201871010121-王方《面向对象程序设计(Java)》第四周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

  4. PHP将图片转base64格式函数

    base64的好处是什么?今天在跟小伙伴讨论这个问题,要是全站用Php把图片转为base64行不行? 1. 提升性能: 网页上的每一个图片,都是需要消耗一个 http 请求下载而来的, 图片的下载始终 ...

  5. Linux——清除服务器的日志文件

    前言 无论多大的磁盘都遭不住日志文件的糟蹋啊,所以还是需要定时的清除一下. 命令 查找所有.log结尾的文件删除 find / -name "*.log" -exec rm -rv ...

  6. ActiveMQ消息可靠性-签收

    非事务模式下消费者签收 动签收就像快递到达时,快递寄送点给你签收了,不用你自己去签收,而手动签收就是必须我本人签收, 自动签收(默认为自动签收) 手动签收:能够避免消息的重复消费 当设置为手动签收时, ...

  7. CAJViewer 去除右上角闪动的图标

    打开CMD,粘贴如下代码: %homedrive% cd "%userprofile%\Documents\My eBooks\" del ad0.xml md ad0.xml m ...

  8. centos virtualbox虚拟机无法连接外网

    各种方法都试了,不好使. 最后重启了很多次,最后一次成功了... ----详情---- 发生的原因是因为突然断电导致的异常. 先通过systemctl restart network 来启动,结果报错 ...

  9. SpringBoot之邮件服务

    springboot 邮件服务 今天在看网上学习微服务的时候顺遍看到了一些关于springboot的文章,写的springboot拓展功能就顺遍学习了一下,接下来给大家分享一下springboot封装 ...

  10. Python语言基础考察点:python语言基础常见考题(一)

    一.python是静态还是动态类型?是强类型还是弱类型? 1.动态强类型语言(不少人误以为是弱类型) 不要傻傻分不清 2.动态还是静态指的是编译期还是运行期确定类型 3.强类型指的是不会发生隐式类型转 ...