gRPC 是一个高性能、开源和通用的 RPC 框架,面向移动和 HTTP/2 设计。git
gRPC 基于 HTTP/2 标准设计,带来诸如双向流、流控、头部压缩、单 TCP 链接上的多复用请求等特。这些特性使得其在移动设备上表现更好,更省电和节省空间占用。github
gRPC 是一个很流行的现代化 RPC 框架,它以 HTTP/2 为通讯协议基础,gRPC 默认使用 protocol buffers 做为接口定义语言,来描述服务接口和有效载荷消息结构。web
尽管 gRPC 有不少应用,可是更为经常使用的仍是基于 HTTP/1.1 的 REST 服务,应用更广,那么可否让 gRPC 同时提供 REST 服务呢?答案是确定的,如今有一个实验性的项目(gRPC HTTP API
)正在进行,若是以为这个项目不错,欢迎在 Github 上进行反馈,将你的意见反馈给 gRPC 团队或者去点个赞以提高项目的优先级 https://github.com/grpc/grpc-dotnet/issues/167json
首先咱们来看一下 proto file:api
syntax = "proto3"; // import "google/api/annotations.proto"; package greet.v1; service Greeter { rpc SayHello (HelloRequest) returns (HelloReply) { option (google.api.http) = { get: "/v1/greeter/{name}" }; } rpc SayHelloFrom (HelloRequestFrom) returns (HelloReply) { option (google.api.http) = { post: "/v1/greeter" body: "*" }; } } message HelloRequest { string name = 1; } message HelloRequestFrom { string name = 1; string from = 2; } message HelloReply { string message = 1; }
和以前相比的变化就是引入了 google/api/annotations.proto
,而后在声明方法的地方声明了 http 请求的方式和路由性能优化
除了 proto file 变化以外,咱们还须要引用 Microsoft.AspNetCore.Grpc.HttpApi
这个包,为了更好的和 swagger 整合,也能够引用 Microsoft.AspNetCore.Grpc.Swagger
这是一个 swagger 的扩展服务器
在 Startup
中注册服务:框架
services.AddGrpcHttpApi();
若是引用了 swagger,也要注册相应的服务:async
services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" }); }) .AddGrpcSwagger();
这样就能够了post
客户端调用示例以下:
using var client = new HttpClient() { DefaultRequestVersion = HttpVersion.Version20, DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher, }; await InvokeHelper.TryInvokeAsync(async () => { var responseText = await client.GetStringAsync("https://localhost:5001/v1/greeter/test"); Console.WriteLine($"Response from https endpoint: {responseText}"); }); await InvokeHelper.TryInvokeAsync(async () => { var responseText = await client.GetStringAsync("http://localhost:5000/v1/greeter/test"); Console.WriteLine($"Response from http endpoint: {responseText}"); }); // await InvokeHelper.TryInvokeAsync(async () => { var responseText = await client.GetStringAsync("http://localhost:5000/v1/todo"); Console.WriteLine($"Response from todo endpoint: {responseText}"); });
客户端输出示例:
服务器端输出示例:
完整的测试代码能够在 Github 获取 https://github.com/WeihanLi/SamplesInPractice/tree/master/GrpcSample
如今的 JSON 序列化是基于Google.Protobuf
,这个实现有两个问题:
async
)须要在最终用户的源代码中添加 google / api / annotations.proto
和 google / api / http.proto
,以便Protobuf编译器能够将它们与用户的proto文件一块儿加载。 若是以某种方式用户没必要关心这些文件,那将是更好的开发人员体验。
这个项目使用下来感受仍是挺方便的,至关于在 proto
文件中加了 http 请求相关的注解,就能够自动提供 REST 服务,这样对于 gRPC 和 REST 服务的整合就很方便了
惟一让我以为有一些美中不足的地方就是 http 只支持 Http2,若是 http 协议要支持 http1.1 的话,http请求 必需要 https
,若是是 http2 就能够比较好的支持 http,可是大部分的客户端都是 httpClient 都是直接请求的,大多没有设置过 Http Version,要手动设置 http2 才能够
若是以为还不错,记得去 GitHub 上反馈哈 https://github.com/grpc/grpc-dotnet/issues/167