.NET Core 尝试 GRPC 进行远程调用demo
创建好项目后,我们需要引用Nuget包。
Google.Protobuf
Grpc.Net.Client
Grpc.Tools
Grpc.AspNetCore
正常是有一个实例的文件的。
greet.proto
可以顺着他的写法,编写你所需要实现的一些逻辑代码。
试着随便写一下其他方法并实现。
Feed.proto
using Grpc.Core; using GrpcService1.Protos; using System.Threading.Tasks; namespace GrpcService1.Services { public class FeedService : Feed.FeedBase { public override Task<MenusResponse> TodayMenus(MenusRequest m, ServerCallContext context) => Task.FromResult(new MenusResponse() { Message = $"你已成功预订今日菜单,早餐:{m.Breakfast},午餐:{m.Lunch},晚餐:{m.Dinner}" }); public override Task<MenusResponse> TomorrowMenus(MenusRequest m, ServerCallContext context) => Task.FromResult(new MenusResponse() { Message = $"你已成功预订明日菜单,早餐:{m.Breakfast},午餐:{m.Lunch},晚餐:{m.Dinner}" }); } }
如果 Feed 引用失败。可以看下 Feed.proto 属性
还需要在 Startup.cs 引用一下服务
app.UseEndpoints(endpoints => { endpoints.MapGrpcService<GreeterService>(); endpoints.MapGrpcService<FeedService>(); 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"); }); });
Program.cs 允许下其他IP的调用 50051端口号
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public static IHostBuilder CreateHostBuilder(string[] args) => 2 Host.CreateDefaultBuilder(args) 3 .ConfigureWebHostDefaults(webBuilder => 4 { 5 webBuilder.UseStartup<Startup>(); 6 webBuilder.ConfigureKestrel(options=> { 7 // 允许本地调用 8 options.ListenLocalhost(50051,a=>a.Protocols=Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http2); 9 10 // 允许所有IP调用 11 options.ListenAnyIP(50051); 12 }); 13 });
launchSettings.json
这个端口也需要修改一下。
这样我们的GRPC服务就能调用成功了。
创建一个控制台程序
还是引用之前的那几个Nuget包。
Grpc.Core
然后把 GRPC 项目的 proto 文件复制过来。
我们就可以直接调用 GRPC 的方法了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 class Program 2 { 3 static async Task Main(string[] args) 4 { 5 Console.WriteLine("Hello World!"); 6 var channel = new Channel("localhost:50051", ChannelCredentials.Insecure); 7 var client = new Feed.FeedClient(channel); 8 var response =await client.TodayMenusAsync(new MenusRequest() { Breakfast="馒头油条豆浆",Lunch="鱼香肉丝",Dinner="蛋炒饭"}); 9 Console.WriteLine(response.Message); 10 response = await client.TomorrowMenusAsync(new MenusRequest() { Breakfast = "皮蛋瘦肉粥", Lunch = "鸡丝凉面", Dinner = "减肥不吃" }); 11 Console.WriteLine(response.Message); 12 Console.ReadLine(); 13 } 14 }
本地运行两个项目。
可以看到我们已经调用成功了。很完美。
备注:
我们每次引用或者复制新的 proto 的文件过来,我们项目的编辑项目文件就会多一个这个。
客户端
<ItemGroup> <Protobuf Update="Protos\Feed.proto" GrpcServices="Client" />
</ItemGroup>
服务端
<ItemGroup> <Protobuf Update="Protos\LuCat.proto" GrpcServices="Server" /> </ItemGroup>
正常项目肯定不止一个 proto 文件的。可以修改成这样,下次复制或者新建,就不会多了。
客户端
<ItemGroup> <Protobuf Include="Protos\*.proto" GrpcServices="Client" Link="Protos\%(RecursiveDir)%(Filename)%(Extension)" /> </ItemGroup>
服务端
<ItemGroup> <Protobuf Include="Protos\*.proto" GrpcServices="Server" Link="Protos\%(RecursiveDir)%(Filename)%(Extension)" /> </ItemGroup>