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