gRPC-Web di aplikasi gRPC ASP.NET Core

Oleh James Newton-King

Pelajari cara mengonfigurasi layanan gRPC ASP.NET Core yang ada agar dapat dipanggil dari aplikasi browser, menggunakan protokol gRPC-Web . gRPC-Web memungkinkan JavaScript browser dan Blazor aplikasi untuk memanggil layanan gRPC. Tidak dimungkinkan untuk memanggil layanan HTTP/2 gRPC dari aplikasi berbasis browser. Layanan gRPC yang dihosting di ASP.NET Core dapat dikonfigurasi untuk mendukung gRPC-Web bersama HTTP/2 gRPC.

Untuk petunjuk tentang menambahkan layanan gRPC ke aplikasi ASP.NET Core yang ada, lihat Menambahkan layanan gRPC ke aplikasi ASP.NET Core.

Untuk instruksi tentang membuat proyek gRPC, lihat Membuat klien dan server .NET Core gRPC di ASP.NET Core.

ASP.NET Core gRPC-Web versus Envoy

Ada dua pilihan cara menambahkan gRPC-Web ke aplikasi ASP.NET Core:

  • Mendukung gRPC-Web bersama gRPC HTTP/2 di ASP.NET Core. Opsi ini menggunakan middleware yang disediakan oleh Grpc.AspNetCore.Web paket.
  • Gunakan dukungan gRPC-Web proksi Envoy untuk menerjemahkan gRPC-Web ke http/2 gRPC. Panggilan yang diterjemahkan kemudian diteruskan ke aplikasi ASP.NET Core.

Ada pro dan kontra untuk setiap pendekatan. Jika lingkungan aplikasi sudah menggunakan Envoy sebagai proksi, mungkin masuk akal untuk juga menggunakan Envoy untuk memberikan dukungan gRPC-Web. Untuk solusi dasar untuk gRPC-Web yang hanya memerlukan ASP.NET Core, Grpc.AspNetCore.Web adalah pilihan yang baik.

Mengonfigurasikan gRPC-Web di ASP.NET Core

Layanan gRPC yang dihosting di ASP.NET Core dapat dikonfigurasi untuk mendukung gRPC-Web bersama HTTP/2 gRPC. gRPC-Web tidak memerlukan perubahan apa pun pada layanan. Satu-satunya modifikasi adalah dalam mengatur middleware di Program.cs.

Untuk mengaktifkan gRPC-Web dengan layanan gRPC ASP.NET Core:

  • Tambahkan referensi ke Grpc.AspNetCore.Web paket.
  • Konfigurasikan aplikasi untuk menggunakan gRPC-Web dengan menambahkan UseGrpcWeb dan EnableGrpcWeb ke Program.cs:
using GrpcGreeter.Services;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddGrpc();

var app = builder.Build();

app.UseGrpcWeb();

app.MapGrpcService<GreeterService>().EnableGrpcWeb();
app.MapGet("/", () => "This gRPC service is gRPC-Web enabled and is callable from browser apps uisng the gRPC-Web protocal");

app.Run();

Kode sebelumnya:

  • Menambahkan middleware gRPC-Web, UseGrpcWeb, setelah perutean dan sebelum titik akhir.
  • Menentukan bahwa endpoints.MapGrpcService<GreeterService>() metode mendukung gRPC-Web dengan EnableGrpcWeb.

Atau, middleware gRPC-Web dapat dikonfigurasi sehingga semua layanan mendukung gRPC-Web secara default dan EnableGrpcWeb tidak diperlukan. Tentukan new GrpcWebOptions { DefaultEnabled = true } kapan middleware ditambahkan.

using GrpcGreeter.Services;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddGrpc();

var app = builder.Build();

app.UseGrpcWeb(new GrpcWebOptions { DefaultEnabled = true });

app.MapGrpcService<GreeterService>().EnableGrpcWeb();
app.MapGet("/", () => "All gRPC service are supported by default in this example, and are callable from browser apps uisng the gRPC-Web protocal");

app.Run();

Catatan

Ada masalah yang diketahui yang menyebabkan gRPC-Web gagal ketika dihosting oleh HTTP.sys di .NET Core 3.x.

Solusi untuk membuat gRPC-Web bekerja di HTTP.sys tersedia di Grpc-web eksperimental dan UseHttpSys()? (grpc/grpc-dotnet #853).

gRPC-Web dan CORS

Keamanan browser mencegah halaman web membuat permintaan ke domain yang berbeda dari yang melayani halaman web. Pembatasan ini berlaku untuk melakukan panggilan gRPC-Web dengan aplikasi browser. Misalnya, aplikasi browser yang dilayani oleh https://www.contoso.com diblokir agar tidak memanggil layanan gRPC-Web yang dihosting di https://services.contoso.com. Berbagi Sumber Daya Lintas Asal (CORS) dapat digunakan untuk melonggarkan pembatasan ini.

Untuk mengizinkan aplikasi browser melakukan panggilan gRPC-Web lintas asal, siapkan CORS di ASP.NET Core. Gunakan dukungan CORS bawaan, dan ekspos header khusus gRPC dengan WithExposedHeaders.

using GrpcGreeter.Services;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddGrpc();

builder.Services.AddCors(o => o.AddPolicy("AllowAll", builder =>
{
    builder.AllowAnyOrigin()
            .AllowAnyMethod()
            .AllowAnyHeader()
            .WithExposedHeaders("Grpc-Status", "Grpc-Message", "Grpc-Encoding", "Grpc-Accept-Encoding");
}));

var app = builder.Build();

app.UseGrpcWeb();
app.UseCors();

app.MapGrpcService<GreeterService>().EnableGrpcWeb()
                                    .RequireCors("AllowAll");

app.MapGet("/", () => "This gRPC service is gRPC-Web enabled, CORS enabled, and is callable from browser apps uisng the gRPC-Web protocal");

app.Run();

Kode sebelumnya:

  • AddCors Panggilan untuk menambahkan layanan CORS dan mengonfigurasi kebijakan CORS yang mengekspos header khusus gRPC.
  • UseCors Panggilan untuk menambahkan middleware CORS setelah konfigurasi perutean dan sebelum konfigurasi titik akhir.
  • Menentukan bahwa endpoints.MapGrpcService<GreeterService>() metode mendukung CORS dengan RequireCors.

gRPC-Web dan streaming

GRPC tradisional melalui HTTP/2 mendukung klien, server, dan streaming dua arah. gRPC-Web menawarkan dukungan terbatas untuk streaming:

  • Klien browser gRPC-Web tidak mendukung panggilan streaming klien dan metode streaming dua arah.
  • Klien gRPC-Web .NET tidak mendukung panggilan streaming klien dan metode streaming dua arah melalui HTTP/1.1.
  • ASP.NET layanan gRPC Core yang dihosting di Azure App Service dan IIS tidak mendukung streaming dua arah.

Saat menggunakan gRPC-Web, kami hanya merekomendasikan penggunaan metode unary dan metode streaming server.

Protokol HTTP

Templat layanan ASP.NET Core gRPC, yang disertakan dalam .NET SDK, membuat aplikasi yang hanya dikonfigurasi untuk HTTP/2. Ini adalah default yang baik ketika aplikasi hanya mendukung gRPC tradisional melalui HTTP/2. gRPC-Web, namun, berfungsi dengan HTTP/1.1 dan HTTP/2. Beberapa platform, seperti UWP atau Unity, tidak dapat menggunakan HTTP/2. Untuk mendukung semua aplikasi klien, konfigurasikan server untuk mengaktifkan HTTP/1.1 dan HTTP/2.

Perbarui protokol default di appsettings.json:

{
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http1AndHttp2"
    }
  }
}

Atau, konfigurasikan Kestrel titik akhir dalam kode startup.

Mengaktifkan HTTP/1.1 dan HTTP/2 pada port yang sama memerlukan TLS untuk negosiasi protokol. Untuk informasi selengkapnya, lihat negosiasi protokol gRPC ASP.NET Core.

Memanggil gRPC-Web dari browser

Aplikasi browser dapat menggunakan gRPC-Web untuk memanggil layanan gRPC. Ada beberapa persyaratan dan batasan saat memanggil layanan gRPC dengan gRPC-Web dari browser:

  • Server harus berisi konfigurasi untuk mendukung gRPC-Web.
  • Streaming klien dan panggilan streaming dua arah tidak didukung. Streaming server didukung.
  • Memanggil layanan gRPC pada domain yang berbeda memerlukan konfigurasi CORS di server.

Klien JavaScript gRPC-Web

Klien JavaScript gRPC-Web ada. Untuk petunjuk tentang cara menggunakan gRPC-Web dari JavaScript, lihat menulis kode klien JavaScript dengan gRPC-Web.

Mengonfigurasi gRPC-Web dengan klien .NET gRPC

Klien .NET gRPC dapat dikonfigurasi untuk melakukan panggilan gRPC-Web. Ini berguna untuk Blazor WebAssembly aplikasi, yang dihosting di browser dan memiliki batasan HTTP kode JavaScript yang sama. Memanggil gRPC-Web dengan klien .NET sama dengan HTTP/2 gRPC. Satu-satunya modifikasi adalah bagaimana saluran dibuat.

Untuk menggunakan gRPC-Web:

  • Tambahkan referensi ke Grpc.Net.Client.Web paket.
  • Pastikan referensi ke Grpc.Net.Client paket adalah versi 2.29.0 atau yang lebih baru.
  • Konfigurasikan saluran untuk menggunakan GrpcWebHandler:
var channel = GrpcChannel.ForAddress("https://localhost:53305", new GrpcChannelOptions
{
    HttpHandler = new GrpcWebHandler(new HttpClientHandler())
});

var client = new Greeter.GreeterClient(channel);
var response = await client.SayHelloAsync(
                  new HelloRequest { Name = "GreeterClient" });

Kode sebelumnya:

  • Mengonfigurasi saluran untuk menggunakan gRPC-Web.
  • Membuat klien dan melakukan panggilan menggunakan saluran.

GrpcWebHandler memiliki opsi konfigurasi berikut:

  • InnerHandler: Yang mendasar HttpMessageHandler yang membuat permintaan HTTP gRPC, misalnya, HttpClientHandler.
  • GrpcWebMode: Jenis enumerasi yang menentukan apakah permintaan Content-Type HTTP gRPC adalah application/grpc-web atau application/grpc-web-text.
    • GrpcWebMode.GrpcWeb mengonfigurasi pengiriman konten tanpa pengodean. Nilai default.
    • GrpcWebMode.GrpcWebText mengonfigurasi konten yang dikodekan base64. Diperlukan untuk panggilan streaming server di browser.
  • HttpVersion: Protokol Version HTTP yang digunakan untuk mengatur HttpRequestMessage.Version pada permintaan HTTP gRPC yang mendasar. gRPC-Web tidak memerlukan versi tertentu dan tidak mengambil alih default kecuali ditentukan.

Penting

Klien gRPC yang dihasilkan memiliki metode sinkron dan asinkron untuk memanggil metode unary. Misalnya, SayHello sinkron, dan SayHelloAsync asinkron. Metode asinkron selalu diperlukan dalam Blazor WebAssembly. Memanggil metode sinkron di Blazor WebAssembly aplikasi menyebabkan aplikasi menjadi tidak responsif.

Menggunakan pabrik klien gRPC dengan gRPC-Web

Buat klien .NET yang kompatibel dengan gRPC-Web menggunakan pabrik klien gRPC:

  • Tambahkan referensi paket ke file proyek untuk paket berikut:
  • Daftarkan klien gRPC dengan injeksi dependensi (DI) menggunakan metode ekstensi generik AddGrpcClient . Dalam aplikasi Blazor WebAssembly , layanan terdaftar dengan DI di Program.cs.
  • Konfigurasikan GrpcWebHandlerConfigurePrimaryHttpMessageHandler menggunakan metode ekstensi.
builder.Services
    .AddGrpcClient<Greet.GreeterClient>(options =>
    {
        options.Address = new Uri("https://localhost:5001");
    })
    .ConfigurePrimaryHttpMessageHandler(
        () => new GrpcWebHandler(new HttpClientHandler()));

Untuk informasi selengkapnya, lihat integrasi pabrik klien gRPC di .NET.

Sumber daya tambahan

Pelajari cara mengonfigurasi layanan gRPC ASP.NET Core yang ada agar dapat dipanggil dari aplikasi browser, menggunakan protokol gRPC-Web . gRPC-Web memungkinkan JavaScript browser dan Blazor aplikasi untuk memanggil layanan gRPC. Tidak dimungkinkan untuk memanggil layanan HTTP/2 gRPC dari aplikasi berbasis browser. Layanan gRPC yang dihosting di ASP.NET Core dapat dikonfigurasi untuk mendukung gRPC-Web bersama HTTP/2 gRPC.

Untuk petunjuk tentang menambahkan layanan gRPC ke aplikasi ASP.NET Core yang ada, lihat Menambahkan layanan gRPC ke aplikasi ASP.NET Core.

Untuk instruksi tentang membuat proyek gRPC, lihat Membuat klien dan server .NET Core gRPC di ASP.NET Core.

ASP.NET Core gRPC-Web versus Envoy

Ada dua pilihan cara menambahkan gRPC-Web ke aplikasi ASP.NET Core:

  • Mendukung gRPC-Web bersama gRPC HTTP/2 di ASP.NET Core. Opsi ini menggunakan middleware yang disediakan oleh Grpc.AspNetCore.Web paket.
  • Gunakan dukungan gRPC-Web proksi Envoy untuk menerjemahkan gRPC-Web ke http/2 gRPC. Panggilan yang diterjemahkan kemudian diteruskan ke aplikasi ASP.NET Core.

Ada pro dan kontra untuk setiap pendekatan. Jika lingkungan aplikasi sudah menggunakan Envoy sebagai proksi, mungkin masuk akal untuk juga menggunakan Envoy untuk memberikan dukungan gRPC-Web. Untuk solusi dasar untuk gRPC-Web yang hanya memerlukan ASP.NET Core, Grpc.AspNetCore.Web adalah pilihan yang baik.

Mengonfigurasikan gRPC-Web di ASP.NET Core

Layanan gRPC yang dihosting di ASP.NET Core dapat dikonfigurasi untuk mendukung gRPC-Web bersama HTTP/2 gRPC. gRPC-Web tidak memerlukan perubahan apa pun pada layanan. Satu-satunya modifikasi adalah dalam mengatur middelware di Program.cs.

Untuk mengaktifkan gRPC-Web dengan layanan gRPC ASP.NET Core:

  • Tambahkan referensi ke Grpc.AspNetCore.Web paket.
  • Konfigurasikan aplikasi untuk menggunakan gRPC-Web dengan menambahkan UseGrpcWeb dan EnableGrpcWeb ke Program.cs:
using GrpcGreeter.Services;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddGrpc();

var app = builder.Build();

app.UseGrpcWeb();

app.MapGrpcService<GreeterService>().EnableGrpcWeb();
app.MapGet("/", () => "This gRPC service is gRPC-Web enabled and is callable from browser apps uisng the gRPC-Web protocal");

app.Run();

Kode sebelumnya:

  • Menambahkan middleware gRPC-Web, UseGrpcWeb, setelah perutean dan sebelum titik akhir.
  • Menentukan bahwa endpoints.MapGrpcService<GreeterService>() metode mendukung gRPC-Web dengan EnableGrpcWeb.

Atau, middleware gRPC-Web dapat dikonfigurasi sehingga semua layanan mendukung gRPC-Web secara default dan EnableGrpcWeb tidak diperlukan. Tentukan new GrpcWebOptions { DefaultEnabled = true } kapan middleware ditambahkan.

using GrpcGreeter.Services;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddGrpc();

var app = builder.Build();

app.UseGrpcWeb(new GrpcWebOptions { DefaultEnabled = true });

app.MapGrpcService<GreeterService>().EnableGrpcWeb();
app.MapGet("/", () => "All gRPC service are supported by default in this example, and are callable from browser apps uisng the gRPC-Web protocal");

app.Run();

Catatan

Ada masalah yang diketahui yang menyebabkan gRPC-Web gagal ketika dihosting oleh HTTP.sys di .NET Core 3.x.

Solusi untuk membuat gRPC-Web bekerja di HTTP.sys tersedia di Grpc-web eksperimental dan UseHttpSys()? (grpc/grpc-dotnet #853).

gRPC-Web dan CORS

Keamanan browser mencegah halaman web membuat permintaan ke domain yang berbeda dari yang melayani halaman web. Pembatasan ini berlaku untuk melakukan panggilan gRPC-Web dengan aplikasi browser. Misalnya, aplikasi browser yang dilayani oleh https://www.contoso.com diblokir agar tidak memanggil layanan gRPC-Web yang dihosting di https://services.contoso.com. Berbagi Sumber Daya Lintas Asal (CORS) dapat digunakan untuk melonggarkan pembatasan ini.

Untuk mengizinkan aplikasi browser melakukan panggilan gRPC-Web lintas asal, siapkan CORS di ASP.NET Core. Gunakan dukungan CORS bawaan, dan ekspos header khusus gRPC dengan WithExposedHeaders.

using GrpcGreeter.Services;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddGrpc();

builder.Services.AddCors(o => o.AddPolicy("AllowAll", builder =>
{
    builder.AllowAnyOrigin()
            .AllowAnyMethod()
            .AllowAnyHeader()
            .WithExposedHeaders("Grpc-Status", "Grpc-Message", "Grpc-Encoding", "Grpc-Accept-Encoding");
}));

var app = builder.Build();

app.UseGrpcWeb();
app.UseCors();

app.MapGrpcService<GreeterService>().EnableGrpcWeb()
                                    .RequireCors("AllowAll");

app.MapGet("/", () => "This gRPC service is gRPC-Web enabled, CORS enabled, and is callable from browser apps uisng the gRPC-Web protocal");

app.Run();

Kode sebelumnya:

  • AddCors Panggilan untuk menambahkan layanan CORS dan mengonfigurasi kebijakan CORS yang mengekspos header khusus gRPC.
  • UseCors Panggilan untuk menambahkan middleware CORS setelah konfigurasi perutean dan sebelum konfigurasi titik akhir.
  • Menentukan bahwa endpoints.MapGrpcService<GreeterService>() metode mendukung CORS dengan RequireCors.

gRPC-Web dan streaming

GRPC tradisional melalui HTTP/2 mendukung klien, server, dan streaming dua arah. gRPC-Web menawarkan dukungan terbatas untuk streaming:

  • Klien browser gRPC-Web tidak mendukung panggilan streaming klien dan metode streaming dua arah.
  • Klien gRPC-Web .NET tidak mendukung panggilan streaming klien dan metode streaming dua arah melalui HTTP/1.1.
  • ASP.NET layanan gRPC Core yang dihosting di Azure App Service dan IIS tidak mendukung streaming dua arah.

Saat menggunakan gRPC-Web, kami hanya merekomendasikan penggunaan metode unary dan metode streaming server.

Protokol HTTP

Templat layanan ASP.NET Core gRPC, yang disertakan dalam .NET SDK, membuat aplikasi yang hanya dikonfigurasi untuk HTTP/2. Ini adalah default yang baik ketika aplikasi hanya mendukung gRPC tradisional melalui HTTP/2. gRPC-Web, namun, berfungsi dengan HTTP/1.1 dan HTTP/2. Beberapa platform, seperti UWP atau Unity, tidak dapat menggunakan HTTP/2. Untuk mendukung semua aplikasi klien, konfigurasikan server untuk mengaktifkan HTTP/1.1 dan HTTP/2.

Perbarui protokol default di appsettings.json:

{
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http1AndHttp2"
    }
  }
}

Atau, konfigurasikan Kestrel titik akhir dalam kode startup.

Mengaktifkan HTTP/1.1 dan HTTP/2 pada port yang sama memerlukan TLS untuk negosiasi protokol. Untuk informasi selengkapnya, lihat negosiasi protokol gRPC ASP.NET Core.

Memanggil gRPC-Web dari browser

Aplikasi browser dapat menggunakan gRPC-Web untuk memanggil layanan gRPC. Ada beberapa persyaratan dan batasan saat memanggil layanan gRPC dengan gRPC-Web dari browser:

  • Server harus berisi konfigurasi untuk mendukung gRPC-Web.
  • Streaming klien dan panggilan streaming dua arah tidak didukung. Streaming server didukung.
  • Memanggil layanan gRPC pada domain yang berbeda memerlukan konfigurasi CORS di server.

Klien JavaScript gRPC-Web

Klien JavaScript gRPC-Web ada. Untuk petunjuk tentang cara menggunakan gRPC-Web dari JavaScript, lihat menulis kode klien JavaScript dengan gRPC-Web.

Mengonfigurasi gRPC-Web dengan klien .NET gRPC

Klien .NET gRPC dapat dikonfigurasi untuk melakukan panggilan gRPC-Web. Ini berguna untuk Blazor WebAssembly aplikasi, yang dihosting di browser dan memiliki batasan HTTP kode JavaScript yang sama. Memanggil gRPC-Web dengan klien .NET sama dengan HTTP/2 gRPC. Satu-satunya modifikasi adalah bagaimana saluran dibuat.

Untuk menggunakan gRPC-Web:

  • Tambahkan referensi ke Grpc.Net.Client.Web paket.
  • Pastikan referensi ke Grpc.Net.Client paket adalah versi 2.29.0 atau yang lebih baru.
  • Konfigurasikan saluran untuk menggunakan GrpcWebHandler:
var channel = GrpcChannel.ForAddress("https://localhost:53305", new GrpcChannelOptions
{
    HttpHandler = new GrpcWebHandler(new HttpClientHandler())
});

var client = new Greeter.GreeterClient(channel);
var response = await client.SayHelloAsync(
                  new HelloRequest { Name = "GreeterClient" });

Kode sebelumnya:

  • Mengonfigurasi saluran untuk menggunakan gRPC-Web.
  • Membuat klien dan melakukan panggilan menggunakan saluran.

GrpcWebHandler memiliki opsi konfigurasi berikut:

  • InnerHandler: Yang mendasar HttpMessageHandler yang membuat permintaan HTTP gRPC, misalnya, HttpClientHandler.
  • GrpcWebMode: Jenis enumerasi yang menentukan apakah permintaan Content-Type HTTP gRPC adalah application/grpc-web atau application/grpc-web-text.
    • GrpcWebMode.GrpcWeb mengonfigurasi pengiriman konten tanpa pengodean. Nilai default.
    • GrpcWebMode.GrpcWebText mengonfigurasi konten yang dikodekan base64. Diperlukan untuk panggilan streaming server di browser.
  • HttpVersion: Protokol Version HTTP yang digunakan untuk mengatur HttpRequestMessage.Version pada permintaan HTTP gRPC yang mendasar. gRPC-Web tidak memerlukan versi tertentu dan tidak mengambil alih default kecuali ditentukan.

Penting

Klien gRPC yang dihasilkan memiliki metode sinkron dan asinkron untuk memanggil metode unary. Misalnya, SayHello sinkron, dan SayHelloAsync asinkron. Metode asinkron selalu diperlukan dalam Blazor WebAssembly. Memanggil metode sinkron di Blazor WebAssembly aplikasi menyebabkan aplikasi menjadi tidak responsif.

Menggunakan pabrik klien gRPC dengan gRPC-Web

Buat klien .NET yang kompatibel dengan gRPC-Web menggunakan pabrik klien gRPC:

  • Tambahkan referensi paket ke file proyek untuk paket berikut:
  • Daftarkan klien gRPC dengan injeksi dependensi (DI) menggunakan metode ekstensi generik AddGrpcClient . Dalam aplikasi Blazor WebAssembly , layanan terdaftar dengan DI di Program.cs.
  • Konfigurasikan GrpcWebHandlerConfigurePrimaryHttpMessageHandler menggunakan metode ekstensi.
builder.Services
    .AddGrpcClient<Greet.GreeterClient>(options =>
    {
        options.Address = new Uri("https://localhost:5001");
    })
    .ConfigurePrimaryHttpMessageHandler(
        () => new GrpcWebHandler(new HttpClientHandler()));

Untuk informasi selengkapnya, lihat integrasi pabrik klien gRPC di .NET.

Sumber daya tambahan

Pelajari cara mengonfigurasi layanan gRPC ASP.NET Core yang ada agar dapat dipanggil dari aplikasi browser, menggunakan protokol gRPC-Web . gRPC-Web memungkinkan JavaScript browser dan Blazor aplikasi untuk memanggil layanan gRPC. Tidak dimungkinkan untuk memanggil layanan HTTP/2 gRPC dari aplikasi berbasis browser. Layanan gRPC yang dihosting di ASP.NET Core dapat dikonfigurasi untuk mendukung gRPC-Web bersama HTTP/2 gRPC.

Untuk petunjuk tentang menambahkan layanan gRPC ke aplikasi ASP.NET Core yang ada, lihat Menambahkan layanan gRPC ke aplikasi ASP.NET Core.

Untuk instruksi tentang membuat proyek gRPC, lihat Membuat klien dan server .NET Core gRPC di ASP.NET Core.

ASP.NET Core gRPC-Web versus Envoy

Ada dua pilihan cara menambahkan gRPC-Web ke aplikasi ASP.NET Core:

  • Mendukung gRPC-Web bersama gRPC HTTP/2 di ASP.NET Core. Opsi ini menggunakan middleware yang disediakan oleh Grpc.AspNetCore.Web paket.
  • Gunakan dukungan gRPC-Web proksi Envoy untuk menerjemahkan gRPC-Web ke http/2 gRPC. Panggilan yang diterjemahkan kemudian diteruskan ke aplikasi ASP.NET Core.

Ada pro dan kontra untuk setiap pendekatan. Jika lingkungan aplikasi sudah menggunakan Envoy sebagai proksi, mungkin masuk akal untuk juga menggunakan Envoy untuk memberikan dukungan gRPC-Web. Untuk solusi dasar untuk gRPC-Web yang hanya memerlukan ASP.NET Core, Grpc.AspNetCore.Web adalah pilihan yang baik.

Mengonfigurasikan gRPC-Web di ASP.NET Core

Layanan gRPC yang dihosting di ASP.NET Core dapat dikonfigurasi untuk mendukung gRPC-Web bersama HTTP/2 gRPC. gRPC-Web tidak memerlukan perubahan apa pun pada layanan. Satu-satunya modifikasi adalah konfigurasi startup.

Untuk mengaktifkan gRPC-Web dengan layanan gRPC ASP.NET Core:

  • Tambahkan referensi ke Grpc.AspNetCore.Web paket.
  • Konfigurasikan aplikasi untuk menggunakan gRPC-Web dengan menambahkan UseGrpcWeb dan EnableGrpcWeb ke Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
    services.AddGrpc();
}

public void Configure(IApplicationBuilder app)
{
    app.UseRouting();

    app.UseGrpcWeb(); // Must be added between UseRouting and UseEndpoints

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGrpcService<GreeterService>().EnableGrpcWeb();
    });
}

Kode sebelumnya:

  • Menambahkan middleware gRPC-Web, UseGrpcWeb, setelah perutean dan sebelum titik akhir.
  • Menentukan bahwa endpoints.MapGrpcService<GreeterService>() metode mendukung gRPC-Web dengan EnableGrpcWeb.

Atau, middleware gRPC-Web dapat dikonfigurasi sehingga semua layanan mendukung gRPC-Web secara default dan EnableGrpcWeb tidak diperlukan. Tentukan new GrpcWebOptions { DefaultEnabled = true } kapan middleware ditambahkan.

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddGrpc();
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseRouting();

        app.UseGrpcWeb(new GrpcWebOptions { DefaultEnabled = true });

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapGrpcService<GreeterService>();
        });
    }
}

Catatan

Ada masalah yang diketahui yang menyebabkan gRPC-Web gagal ketika dihosting oleh HTTP.sys di .NET Core 3.x.

Solusi untuk membuat gRPC-Web bekerja di HTTP.sys tersedia di Grpc-web eksperimental dan UseHttpSys()? (grpc/grpc-dotnet #853).

gRPC-Web dan CORS

Keamanan browser mencegah halaman web membuat permintaan ke domain yang berbeda dari yang melayani halaman web. Pembatasan ini berlaku untuk melakukan panggilan gRPC-Web dengan aplikasi browser. Misalnya, aplikasi browser yang dilayani oleh https://www.contoso.com diblokir agar tidak memanggil layanan gRPC-Web yang dihosting di https://services.contoso.com. Berbagi Sumber Daya Lintas Asal (CORS) dapat digunakan untuk melonggarkan pembatasan ini.

Untuk mengizinkan aplikasi browser melakukan panggilan gRPC-Web lintas asal, siapkan CORS di ASP.NET Core. Gunakan dukungan CORS bawaan, dan ekspos header khusus gRPC dengan WithExposedHeaders.

public void ConfigureServices(IServiceCollection services)
{
    services.AddGrpc();

    services.AddCors(o => o.AddPolicy("AllowAll", builder =>
    {
        builder.AllowAnyOrigin()
               .AllowAnyMethod()
               .AllowAnyHeader()
               .WithExposedHeaders("Grpc-Status", "Grpc-Message", "Grpc-Encoding", "Grpc-Accept-Encoding");
    }));
}

public void Configure(IApplicationBuilder app)
{
    app.UseRouting();

    app.UseGrpcWeb();
    app.UseCors();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGrpcService<GreeterService>().EnableGrpcWeb()
                                                  .RequireCors("AllowAll");
    });
}

Kode sebelumnya:

  • AddCors Panggilan untuk menambahkan layanan CORS dan mengonfigurasi kebijakan CORS yang mengekspos header khusus gRPC.
  • UseCors Panggilan untuk menambahkan middleware CORS setelah konfigurasi perutean dan sebelum konfigurasi titik akhir.
  • Menentukan bahwa endpoints.MapGrpcService<GreeterService>() metode mendukung CORS dengan RequireCors.

gRPC-Web dan streaming

GRPC tradisional melalui HTTP/2 mendukung klien, server, dan streaming dua arah. gRPC-Web menawarkan dukungan terbatas untuk streaming:

  • Klien browser gRPC-Web tidak mendukung panggilan streaming klien dan metode streaming dua arah.
  • Klien gRPC-Web .NET tidak mendukung panggilan streaming klien dan metode streaming dua arah melalui HTTP/1.1.
  • ASP.NET layanan gRPC Core yang dihosting di Azure App Service dan IIS tidak mendukung streaming dua arah.

Saat menggunakan gRPC-Web, kami hanya merekomendasikan penggunaan metode unary dan metode streaming server.

Protokol HTTP

Templat layanan ASP.NET Core gRPC, yang disertakan dalam .NET SDK, membuat aplikasi yang hanya dikonfigurasi untuk HTTP/2. Ini adalah default yang baik ketika aplikasi hanya mendukung gRPC tradisional melalui HTTP/2. gRPC-Web, namun, berfungsi dengan HTTP/1.1 dan HTTP/2. Beberapa platform, seperti UWP atau Unity, tidak dapat menggunakan HTTP/2. Untuk mendukung semua aplikasi klien, konfigurasikan server untuk mengaktifkan HTTP/1.1 dan HTTP/2.

Perbarui protokol default di appsettings.json:

{
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http1AndHttp2"
    }
  }
}

Atau, konfigurasikan Kestrel titik akhir dalam kode startup.

Mengaktifkan HTTP/1.1 dan HTTP/2 pada port yang sama memerlukan TLS untuk negosiasi protokol. Untuk informasi selengkapnya, lihat negosiasi protokol gRPC ASP.NET Core.

Memanggil gRPC-Web dari browser

Aplikasi browser dapat menggunakan gRPC-Web untuk memanggil layanan gRPC. Ada beberapa persyaratan dan batasan saat memanggil layanan gRPC dengan gRPC-Web dari browser:

  • Server harus berisi konfigurasi untuk mendukung gRPC-Web.
  • Streaming klien dan panggilan streaming dua arah tidak didukung. Streaming server didukung.
  • Memanggil layanan gRPC pada domain yang berbeda memerlukan konfigurasi CORS di server.

Klien JavaScript gRPC-Web

Klien JavaScript gRPC-Web ada. Untuk petunjuk tentang cara menggunakan gRPC-Web dari JavaScript, lihat menulis kode klien JavaScript dengan gRPC-Web.

Mengonfigurasi gRPC-Web dengan klien .NET gRPC

Klien .NET gRPC dapat dikonfigurasi untuk melakukan panggilan gRPC-Web. Ini berguna untuk Blazor WebAssembly aplikasi, yang dihosting di browser dan memiliki batasan HTTP kode JavaScript yang sama. Memanggil gRPC-Web dengan klien .NET sama dengan HTTP/2 gRPC. Satu-satunya modifikasi adalah bagaimana saluran dibuat.

Untuk menggunakan gRPC-Web:

  • Tambahkan referensi ke Grpc.Net.Client.Web paket.
  • Pastikan referensi ke Grpc.Net.Client paket adalah versi 2.29.0 atau yang lebih baru.
  • Konfigurasikan saluran untuk menggunakan GrpcWebHandler:
var channel = GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions
    {
        HttpHandler = new GrpcWebHandler(new HttpClientHandler())
    });

var client = new Greeter.GreeterClient(channel);
var response = await client.SayHelloAsync(new HelloRequest { Name = ".NET" });

Kode sebelumnya:

  • Mengonfigurasi saluran untuk menggunakan gRPC-Web.
  • Membuat klien dan melakukan panggilan menggunakan saluran.

GrpcWebHandler memiliki opsi konfigurasi berikut:

  • InnerHandler: Yang mendasar HttpMessageHandler yang membuat permintaan HTTP gRPC, misalnya, HttpClientHandler.
  • GrpcWebMode: Jenis enumerasi yang menentukan apakah permintaan Content-Type HTTP gRPC adalah application/grpc-web atau application/grpc-web-text.
    • GrpcWebMode.GrpcWeb mengonfigurasi pengiriman konten tanpa pengodean. Nilai default.
    • GrpcWebMode.GrpcWebText mengonfigurasi konten yang dikodekan base64. Diperlukan untuk panggilan streaming server di browser.
  • HttpVersion: Protokol Version HTTP yang digunakan untuk mengatur HttpRequestMessage.Version pada permintaan HTTP gRPC yang mendasar. gRPC-Web tidak memerlukan versi tertentu dan tidak mengambil alih default kecuali ditentukan.

Penting

Klien gRPC yang dihasilkan memiliki metode sinkron dan asinkron untuk memanggil metode unary. Misalnya, SayHello sinkron, dan SayHelloAsync asinkron. Metode asinkron selalu diperlukan dalam Blazor WebAssembly. Memanggil metode sinkron di Blazor WebAssembly aplikasi menyebabkan aplikasi menjadi tidak responsif.

Menggunakan pabrik klien gRPC dengan gRPC-Web

Buat klien .NET yang kompatibel dengan gRPC-Web menggunakan pabrik klien gRPC:

  • Tambahkan referensi paket ke file proyek untuk paket berikut:
  • Daftarkan klien gRPC dengan injeksi dependensi (DI) menggunakan metode ekstensi generik AddGrpcClient . Dalam aplikasi Blazor WebAssembly , layanan terdaftar dengan DI di Program.cs.
  • Konfigurasikan GrpcWebHandlerConfigurePrimaryHttpMessageHandler menggunakan metode ekstensi.
builder.Services
    .AddGrpcClient<Greet.GreeterClient>(options =>
    {
        options.Address = new Uri("https://localhost:5001");
    })
    .ConfigurePrimaryHttpMessageHandler(
        () => new GrpcWebHandler(new HttpClientHandler()));

Untuk informasi selengkapnya, lihat integrasi pabrik klien gRPC di .NET.

Sumber daya tambahan