0

From what I understand, it's best to reuse gRPC channels. What is the right way to create multiple code-first clients which share address and handler configurations?

I have multiple ASP.NET gRPC services hosted at the same server/address. I want multiple clients to be configured in the same way and use to the single common channel. For example, I want to configure a GrpcWebHandler and a DelegatingHandler so I can use SetBrowserRequestCredentials. For context, I'm creating these clients in Blazor WebAssembly.

I'm also using the code-first approach with protobuf-net.grpc. But, all the documented examples I could find of ...Services.AddCodeFirstGrpcClient() seem to provide an Address with each client. I assume this results in a separate channel created for each client.

Here is an example repo which I'd like to update with the correct approach. https://github.com/vyrotek/blazor-wasm-codefirst-grpc/blob/main/Example/Client/Program.cs

Vyrotek
  • 5,356
  • 5
  • 45
  • 70
  • There is more than one type authentication. See : https://grpc.io/docs/guides/auth/ Most apps are moving toward OAUTH2 because it is supported on Windows, MAC, and Linux. OAUTH uses tokens for authentication – jdweng Jul 30 '23 at 23:24
  • @jdweng I don't see how your comment is relevant. I'm experienced with OAUTH2 and am intentionally avoiding it to avoid the unnecessary complexity. – Vyrotek Jul 30 '23 at 23:32
  • Following may help https://www.learmoreseekmore.com/2022/04/blazorwasm-cookie-series-part-1-blazor-webassembly-cookie-authentication.html – jdweng Jul 30 '23 at 23:48
  • You are doing an HTTP request and getting back an HTTP Response. A HTTP client opens a new connection for each request and then gets back a response. Then the connection is closed. So when you have multiple clients you have multiple connections. So you are not using a single common channel, you have multiple connections at the transport layer. The application layer will have a common channel to serialize the data at the client and deserialize the data at server. This may just be an issue of understanding the different network layers. – jdweng Jul 31 '23 at 00:03

1 Answers1

0

From what I could find, this seems to be the next best option.

This approach drops protobuf-net.Grpc.ClientFactory and instead creates the services manually.

var baseAddress = new Uri(builder.HostEnvironment.BaseAddress);

builder.Services.AddSingleton(services =>
{
    var httpHandler = new CredentialHandler(new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()));
    return GrpcChannel.ForAddress(baseAddress, new GrpcChannelOptions { HttpHandler = httpHandler });
});

builder.Services.AddScoped(services =>
{
    return services.GetRequiredService<GrpcChannel>().CreateGrpcService<IAuthService>();
});

builder.Services.AddScoped(services =>
{
    return services.GetRequiredService<GrpcChannel>().CreateGrpcService<IWeatherForecastService>();
});
Vyrotek
  • 5,356
  • 5
  • 45
  • 70