一,什么是GRPC?
gRPC 是一种与语言无关的高性能远程过程调用 (RPC) 框架。
gRPC 的主要优点是:
- 现代高性能轻量级 RPC 框架。
- 协定优先 API 开发,默认使用协议缓冲区,允许与语言无关的实现。
- 可用于多种语言的工具,以生成强类型服务器和客户端。
- 支持客户端、服务器和双向流式处理调用。
- 使用 Protobuf 二进制序列化减少对网络的使用。
这些优点使 gRPC 适用于:
- 效率至关重要的轻量级微服务。
- 需要多种语言用于开发的 Polyglot 系统。
- 需要处理流式处理请求或响应的点对点实时服务。
微软介绍地址:https://docs.microsoft.com/zh-cn/aspnet/core/grpc/?view=aspnetcore-3.0
二,我们上代码,远程调用的demo,项目结构如下
接口和实现
ServiceInterface
using MagicOnion; using System; namespace ServiceInterface { public interface IGrpcTestService : IService<IGrpcTestService> { UnaryResult<string> SumAsync(int x, int y); } }
GrpcTestService
using MagicOnion; using MagicOnion.Server; using ServiceInterface; using System; namespace Service { public class GrpcTestService : ServiceBase<IGrpcTestService>, IGrpcTestService { public async UnaryResult<string> SumAsync(int x, int y) => (x + y).ToString(); } }
服务端
Startup
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Runtime.Loader; using System.Threading.Tasks; using Grpc.Core; using MagicOnion.Server; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Service; namespace grpcDemo { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { #region grpc MagicOnionServiceDefinition service = MagicOnionEngine.BuildServerServiceDefinition( ///由于实现不在当前的项目,再新建类库,所以我们需要手动配置加载的程序集 new[] { AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName("Service")) }, new MagicOnionOptions(true) { MagicOnionLogger = new MagicOnionLogToGrpcLogger() } ); Server server = new Server { Services = { service }, Ports = { new ServerPort("localhost", 6000, ServerCredentials.Insecure) }//默认端口是5000 }; server.Start(); #endregion services.AddControllers(); } // 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.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } } }
GrpcServiceController
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Grpc.Core; using MagicOnion.Client; using MagicOnion.Server; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using ServiceInterface; namespace grpcDemo.Controllers { [ApiController] [Route("[controller]")] public class GrpcServiceController : ControllerBase { private readonly ILogger<GrpcServiceController> _logger; public GrpcServiceController(ILogger<GrpcServiceController> logger) { _logger = logger; } public string Get() { return "grpc服务端启动"; } } }
客户端 Program
using Grpc.Core; using MagicOnion.Client; using ServiceInterface; using System; namespace grpcClientDemo { class Program { static void Main(string[] args) { Console.WriteLine("Hello World!"); // 然后你就可以根据IP和端口拿到对于的服务 var channel = new Channel("localhost", 6000, ChannelCredentials.Insecure); var client = MagicOnionClient.Create<IGrpcTestService>(channel); // 调用 var result = client.SumAsync(100, 200).ResponseAsync.Result; Console.WriteLine("Client Received:" + result); var channel2 = new Channel("localhost", 6000, ChannelCredentials.Insecure); var client2 = MagicOnionClient.Create<IGrpcTestService>(channel2); var result2 = client2.SumAsync(100, 200).ResponseAsync.Result; Console.WriteLine("Client Received:" + result2); } } }
启动服务端后再启动客户端,如下图
这样简单的grpc就完成了
PS:如果我们服务端的实现再另一个类库,我们需要将该类库的程序集加载进来,要不然会报错