.Net Core 3.0使用Grpc进行远程过程调用
因为.Net Core3.0已经把Grpc作为一等臣民了,作为爱好新技术的我,当然要尝鲜体验一下了,当然感觉是Grpc作为跨语言的产品做的相当好喽,比起Dubbo这种的,优势和劣势还是比较明显的。
我这里的环境是VS2019以及,Net Core3.0预览5版,.Net Core3.0预览SDK没有随着VS2019一同安装,如果大家想要体验的话,需要先安装.Net Core3.0的SDK,并在VS2019设置中开启.Net Core的预览才可以使用。
* .Net Core 3.0提供了Grpc的模板可以快速生成Grpc Server的模板代码,当然,我这里还是手动去创建项目。
⒈Server端
1.创建一个ASP.NET Core Web应用程序
2.引入依赖
Install-Package Grpc.AspNetCore.Server -pre Install-Package Google.Protobuf Install-Package Grpc.Tools
3.编写Proto文件
syntax = "proto3"; package Service; service UserService{ rpc GetUserById (UserId) returns (User) {} } message UserId{ int32 id = 1; } message User{ int32 id = 1; string username = 2; string password = 3; string phone = 4; string email = 5; }
4.编辑当前项目的csproj文件,配置Proto的生成策略
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>netcoreapp3.0</TargetFramework> </PropertyGroup> <ItemGroup> <Protobuf Include="Protos/*.proto" GrpcServices="Server" OutputDir="%(RelativeDir)" CompileOutputs="false" /> </ItemGroup> <ItemGroup> <None Remove="Protos\user.proto" /> </ItemGroup> <ItemGroup> <PackageReference Include="Google.Protobuf" Version="3.7.0" /> <PackageReference Include="Grpc.AspNetCore.Server" Version="0.1.20-pre1" /> <PackageReference Include="Grpc.Tools" Version="1.20.1"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0-preview5-19227-01" /> </ItemGroup> <ItemGroup> <Protobuf Update="Protos\user.proto"> <OutputDir>%(RelativeDir)</OutputDir> </Protobuf> </ItemGroup> </Project>
5.编写服务的实现
1 using Grpc.Core; 2 using Microsoft.Extensions.Logging; 3 using Service; 4 using System; 5 using System.Collections.Generic; 6 using System.Linq; 7 using System.Threading.Tasks; 8 9 namespace GrpcGreeter.Services 10 { 11 public class UserServiceImpl:UserService.UserServiceBase 12 { 13 public ILogger<UserServiceImpl> _logger; 14 public UserServiceImpl(ILogger<UserServiceImpl> logger) 15 { 16 this._logger = logger; 17 } 18 public static IList<User> users = new List<User> 19 { 20 new User 21 { Id = 1,Username = "fanqi",Password = "admin",Phone="13800138000",Email="fanqi@coreqi.cn" 22 }, 23 new User 24 { 25 Id = 2,Username = "gaoxing",Password="admin",Phone="138001380000",Email = "gaoxing@coreqi.cn" 26 } 27 }; 28 public override Task<User> GetUserById(UserId request, ServerCallContext context) 29 { 30 var httpContext = context.GetHttpContext(); //我没有用到httpContext 31 _logger.LogInformation("成功调用"); 32 User user = users.FirstOrDefault(f => f.Id == request.Id); 33 return Task.FromResult(user); 34 } 35 } 36 }
⒍在Startup中配置Grpc
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Threading.Tasks; 5 using GrpcGreeter.Services; 6 using Microsoft.AspNetCore.Builder; 7 using Microsoft.AspNetCore.Hosting; 8 using Microsoft.AspNetCore.HttpsPolicy; 9 using Microsoft.Extensions.Configuration; 10 using Microsoft.Extensions.DependencyInjection; 11 using Microsoft.Extensions.Hosting; 12 13 namespace GrpcGreeterServer 14 { 15 public class Startup 16 { 17 public Startup(IConfiguration configuration) 18 { 19 Configuration = configuration; 20 } 21 22 public IConfiguration Configuration { get; } 23 24 public void ConfigureServices(IServiceCollection services) 25 { 26 services.AddGrpc(); 27 } 28 29 // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 30 public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 31 { 32 if (env.IsDevelopment()) 33 { 34 app.UseDeveloperExceptionPage(); 35 } 36 37 app.UseRouting(); 38 39 app.UseEndpoints(endpoints => 40 { 41 endpoints.MapGrpcService<UserServiceImpl>(); 42 }); 43 } 44 } 45 }
7.在launchSettings.json中配置Grpc
1 { 2 "profiles": { 3 "GrpcGreeter": { 4 "commandName": "Project", 5 "launchBrowser": false, 6 "applicationUrl": "http://localhost:50051", 7 "environmentVariables": { 8 "ASPNETCORE_ENVIRONMENT": "Development" 9 } 10 } 11 } 12 }
8.在appsettings.json中配置Grpc
1 { 2 "Logging": { 3 "LogLevel": { 4 "Default": "Information", 5 "Microsoft": "Warning", 6 "Microsoft.Hosting.Lifetime": "Information" 7 } 8 }, 9 "AllowedHosts": "*", 10 "Kestrel": { 11 "EndpointDefaults": { 12 "Protocols": "Http2" 13 } 14 } 15 }
⒉Client端
1.创建一个ASP.NET Core Web应用程序
2.引入依赖
1 Install-Package Grpc.Core 2 Install-Package Google.Protobuf 3 Install-Package Grpc.Tools
3.将Server的Proto文件复制到Client项目中来
4.编辑当前项目的csproj文件,配置Proto的生成策略
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>netcoreapp3.0</TargetFramework> </PropertyGroup> <ItemGroup> <None Remove="Protos\greet.proto" /> <None Remove="Protos\user.proto" /> </ItemGroup> <ItemGroup> <Protobuf Include="Protos\greet.proto" GrpcServices="Client"> <CopyToOutputDirectory>Always</CopyToOutputDirectory> <OutputDir>%(RelativeDir)</OutputDir> <CompileOutputs>false</CompileOutputs> <Generator>MSBuild:Compile</Generator> </Protobuf> <Protobuf Include="Protos\user.proto" GrpcServices="Client"> <OutputDir>%(RelativeDir)</OutputDir> <CompileOutputs>false</CompileOutputs> </Protobuf> </ItemGroup> <ItemGroup> <PackageReference Include="Google.Protobuf" Version="3.7.0" /> <PackageReference Include="Grpc.Core" Version="1.20.1" /> <PackageReference Include="Grpc.Tools" Version="1.20.1"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0-preview5-19227-01" /> </ItemGroup> </Project>
5.在代码中使用Grpc
1 public async Task<IActionResult> Index() 2 { 3 var channel = new Channel("localhost:50051", ChannelCredentials.Insecure); 4 var client = new UserService.UserServiceClient(channel); 5 var user = await client.GetUserByIdAsync(new UserId { Id = 1}); 6 await channel.ShutdownAsync(); 7 return Json(new { User = user }); 8 }