文章目錄
ASP.NET Core 的 gRPC-Web 功能
之前筆記 gRPC 在 ASP.NET Core 7 的 JSON 轉碼功能 紀錄到如何使用 Transcoding 讓 gRPC service 同時提供 web rest api 的功能,過程中在 Microsoft 官方文件 gRPC JSON transcoding in ASP.NET Core gRPC apps 看到 Microsoft 官方將 gRPC JSON transcoding 與 gRPC-Web 做比較,所以趁著這個機會一併了解一下相關用法
因為瀏覽器主要使用 HTTP1.1 而 gRPC 則是以 HTTP2 為主,針對這個問題 gRPC 團隊提出的 solution 是在 browser client 與 gRPC service 中間加上一個 proxy (gRPC 團隊使用 Envoy) 用來做 protocol 的轉換,並在 browser 上使用 gRPC-Web (用來連線 proxy 而開發的 JavaScript client library) 來呼叫 gRPC service
ASP.NET Core gRPC-Web 則是不需要額外建置 Envoy 這個 proxy,改由 Grpc.AspNetCore.Web middleware 取代,整體使用上會更加簡潔
基本環境說明
- macOS Ventura 13.2
- .NET SDK 7.0.203
JetBrains Rider 2023.1
使用 gRPC service 預設專案範本
NuGet packages
- Service
- Grpc.AspNetCore.Web 2.52.0
- Client
- Grpc.Net.Client 2.52.0
- Grpc.Net.Client.Web 2.52.0
- Grpc.Tools 2.54.0
- Google.Protobuf 3.22.4
- Service
設定方式
- 新增 NuGet package : Grpc.AspNetCore.Web 2.52.0
註冊 gRPC-Web (修改
Program.cs
)2-1. 逐一啟用
前
using GrpcService1.Services; var builder = WebApplication.CreateBuilder(args); // Additional configuration is required to successfully run gRPC on macOS. // For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go. microsoft.com/fwlink/?linkid=2099682 // Add services to the container. builder.Services.AddGrpc(); var app = builder.Build(); // Configure the HTTP request pipeline. app.MapGrpcService<GreeterService>(); app.MapGet("/", () => "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"); app.Run();
後
using GrpcService1.Services; var builder = WebApplication.CreateBuilder(args); // Additional configuration is required to successfully run gRPC on macOS. // For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go. microsoft.com/fwlink/?linkid=2099682 // Add services to the container. builder.Services.AddGrpc(); var app = builder.Build(); //新增下列這行:使用 gRPC-Web middleware app.UseGrpcWeb(); // 新增 `.EnableGrpcWeb();` 在 `GreeterService` 啟用 gRPC-Web app.MapGrpcService<GreeterService>().EnableGrpcWeb(); app.MapGet("/", () => "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"); app.Run();
2-2. 預設全部啟用
前
using GrpcService1.Services; var builder = WebApplication.CreateBuilder(args); // Additional configuration is required to successfully run gRPC on macOS. // For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go. microsoft.com/fwlink/?linkid=2099682 // Add services to the container. builder.Services.AddGrpc(); var app = builder.Build(); // Configure the HTTP request pipeline. app.MapGrpcService<GreeterService>(); app.MapGet("/", () => "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"); app.Run();
後
using GrpcService1.Services; var builder = WebApplication.CreateBuilder(args); // Additional configuration is required to successfully run gRPC on macOS. // For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go. microsoft.com/fwlink/?linkid=2099682 // Add services to the container. builder.Services.AddGrpc(); var app = builder.Build(); //新增下列這行:使用 gRPC-Web middleware 並預設全部啟用 gRPC-Web app.UseGrpcWeb(new GrpcWebOptions { DefaultEnabled = true }); // Configure the HTTP request pipeline. app.MapGrpcService<GreeterService>(); app.MapGet("/", () => "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"); app.Run();
client 呼叫方式
using Greet;
using Grpc.Net.Client;
using Grpc.Net.Client.Web;
var channel = GrpcChannel.ForAddress("http://localhost:5226", new GrpcChannelOptions
{
//使用 gRPC-Web (Content-Type 會是 application/grpc-web 或 application/grpc-web-text)
HttpHandler = new GrpcWebHandler(new HttpClientHandler())
});
var client = new Greeter.GreeterClient(channel);
Console.WriteLine($"{ (await client.SayHelloAsync(new HelloRequest(){Name = "gRPCCall"})).Message}");
心得
- protocol 本身的限制,只能支援
Unary RPCs
與Server-side Streaming RPCs
- 設定簡單,還不用自行設定 Envoy proxy
- 需要使用 gRPC 方式來使用,不像 gRPC JSON transcoding 可以直接透過 rest api 方式呼叫
完整程式碼:yowko/aspnetcore-grpc-web
參考資訊
文章作者 Yowko Tsai
上次更新 2023-05-05
授權合約
本部落格 (Yowko's Notes) 所有的文章內容(包含圖片),任何轉載行為,必須通知並獲本部落格作者 (Yowko Tsai) 的同意始得轉載,且轉載皆須註明出處與作者。
Yowko's Notes 由 Yowko Tsai 製作,以創用CC 姓名標示-非商業性-相同方式分享 3.0 台灣 授權條款 釋出。