public static GrpcChannel GetGrpcChannel(string grpcServerUrl) { if (grpcChannel == null) { AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", false); var httpHandler = new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()); grpcChannel = GrpcChannel.ForAddress(grpcServerUrl, new GrpcChannelOptions { HttpHandler = httpHandler }); } return(grpcChannel); }
private async Task <IChannelWrapper> HttpClientCreateChannel() { var credentials = await CreateCredentialsAsync(useTestCaOverride : false); string scheme; if (!options.UseTls) { scheme = "http"; } else { scheme = "https"; } var httpClientHandler = new HttpClientHandler(); #if !BLAZOR_WASM httpClientHandler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; if (options.UseTestCa) { var pem = File.ReadAllText("Certs/ca.pem"); var certData = GetBytesFromPem(pem, "CERTIFICATE"); var cert = new X509Certificate2(certData !); httpClientHandler.ClientCertificates.Add(cert); } #endif HttpMessageHandler httpMessageHandler; if (options.GrpcWebMode != null) { var mode = Enum.Parse <GrpcWebMode>(options.GrpcWebMode); httpMessageHandler = new GrpcWebHandler(mode, httpClientHandler) { HttpVersion = new Version(1, 1) }; } else { httpMessageHandler = httpClientHandler; } var channel = GrpcChannel.ForAddress($"{scheme}://{options.ServerHost}:{options.ServerPort}", new GrpcChannelOptions { Credentials = credentials, HttpHandler = httpMessageHandler, LoggerFactory = loggerFactory }); return(new GrpcChannelWrapper(channel)); }
private async Task <IChannelWrapper> HttpClientCreateChannel() { var credentials = await CreateCredentialsAsync(useTestCaOverride : false); string scheme; if (!(options.UseTls ?? false)) { AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); scheme = "http"; } else { scheme = "https"; } var httpClientHandler = new HttpClientHandler(); httpClientHandler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; if (options.UseTestCa ?? false) { var pem = File.ReadAllText("Certs/ca.pem"); var certData = GetBytesFromPem(pem, "CERTIFICATE"); var cert = new X509Certificate2(certData); httpClientHandler.ClientCertificates.Add(cert); } HttpMessageHandler httpMessageHandler; if (options.GrpcWebMode != null) { var mode = Enum.Parse <GrpcWebMode>(options.GrpcWebMode); httpMessageHandler = new GrpcWebHandler(mode, new Version(1, 1), httpClientHandler); } else { httpMessageHandler = httpClientHandler; } var httpClient = new HttpClient(httpMessageHandler); var channel = GrpcChannel.ForAddress($"{scheme}://{options.ServerHost}:{options.ServerPort}", new GrpcChannelOptions { Credentials = credentials, HttpClient = httpClient, LoggerFactory = loggerFactory }); return(new GrpcChannelWrapper(channel)); }
private async Task <IChannelWrapper> HttpClientCreateChannel() { var credentials = await CreateCredentialsAsync(useTestCaOverride : false); string scheme; if (!options.UseTls) { scheme = "http"; } else { scheme = "https"; } HttpMessageHandler httpMessageHandler; if (!options.UseWinHttp) { httpMessageHandler = CreateHttpClientHandler(); } else { httpMessageHandler = CreateWinHttpHandler(); } if (!string.IsNullOrEmpty(options.GrpcWebMode) && !string.Equals(options.GrpcWebMode, "None", StringComparison.OrdinalIgnoreCase)) { var mode = (GrpcWebMode)Enum.Parse(typeof(GrpcWebMode), options.GrpcWebMode); httpMessageHandler = new GrpcWebHandler(mode, httpMessageHandler) { HttpVersion = new Version(1, 1) }; } if (options.UseHttp3) { #if NET6_0_OR_GREATER httpMessageHandler = new Http3DelegatingHandler(httpMessageHandler); #else throw new Exception("HTTP/3 requires .NET 6 or later."); #endif } var channel = GrpcChannel.ForAddress($"{scheme}://{options.ServerHost}:{options.ServerPort}", new GrpcChannelOptions { Credentials = credentials, HttpHandler = httpMessageHandler, LoggerFactory = loggerFactory }); return(new GrpcChannelWrapper(channel)); }
private static GrpcChannel BuildGrpcChannel(WebAssemblyHostBuilder builder, IServiceProvider services) { var baseAddressMessageHandler = services.GetRequiredService <BaseAddressAuthorizationMessageHandler>(); baseAddressMessageHandler.InnerHandler = new HttpClientHandler(); var grpcWebHandler = new GrpcWebHandler(GrpcWebMode.GrpcWeb, baseAddressMessageHandler); var channel = GrpcChannel.ForAddress(builder.HostEnvironment.BaseAddress, new GrpcChannelOptions { HttpHandler = grpcWebHandler }); return(channel); }
private static GrpcChannel BuildGrpcChannel(IServiceProvider services, WebAssemblyHostBuilder builder) { var baseAddressMessageHandler = services.GetRequiredService <BaseAddressAuthorizationMessageHandler>(); baseAddressMessageHandler.InnerHandler = new HttpClientHandler(); var grpcWebHandler = new GrpcWebHandler(GrpcWebMode.GrpcWeb, baseAddressMessageHandler); var channel = GrpcChannel.ForAddress(builder.Configuration[Configuration.BackendUrlKey], new GrpcChannelOptions { HttpHandler = grpcWebHandler }); return(channel); }
public static async Task Main(string[] args) { var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add <App>("#app"); builder.Services.AddAuthorizationCore(); builder.Services.AddScoped <AuthenticationStateProvider, CookieAuthenticationStateProvider>(); var httpClient = new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }; builder.Services.AddScoped(sp => httpClient); var httpHandler = new GrpcWebHandler(GrpcWebMode.GrpcWebText, new HttpClientHandler()); var grpcClient = GrpcChannel.ForAddress(builder.HostEnvironment.BaseAddress, new GrpcChannelOptions { HttpHandler = httpHandler }); builder.Services.AddGrpcClient <BotGameManager.BotGameManagerClient>((services, options) => { options.Address = new Uri(builder.HostEnvironment.BaseAddress); }) .ConfigurePrimaryHttpMessageHandler(() => httpHandler); builder.Services.AddGrpcClient <MultiplayerGameManager.MultiplayerGameManagerClient>((services, options) => { options.Address = new Uri(builder.HostEnvironment.BaseAddress); }) .ConfigurePrimaryHttpMessageHandler(() => httpHandler); var gameSettingsManager = new GameSettingsManager.GameSettingsManagerClient(grpcClient); var settings = await gameSettingsManager.GetSettingsAsync(new Empty()); builder.Services.AddSingleton(_ => settings.MultiplayerSettings); builder.Services.AddSingleton(_ => settings.TwitterSettings); builder.Services.AddSingleton(_ => settings.GoogleAnalyticsSettings); builder.Services.AddSingleton(_ => settings.RecognitionSettings); builder.Services.AddScoped <IBotGameManagerClient, BotGameManagerClient>(); builder.Services.AddScoped <IBotGameService, BotGameService>(); builder.Services.AddScoped <IMultiplayerGameManagerClient, MultiplayerGameManagerClient>(); builder.Services.AddScoped <IMultiplayerGameService, MultiplayerGameService>(); builder.Services.AddGoogleAnalytics(); await builder.Build().RunAsync(); }
private GrpcChannel CreateGrpcWebChannel(TestServerEndpointName endpointName, Version?version) { var grpcWebHandler = new GrpcWebHandler(GrpcWebMode.GrpcWeb); grpcWebHandler.HttpVersion = version; var httpClient = Fixture.CreateClient(endpointName, grpcWebHandler); var channel = GrpcChannel.ForAddress(httpClient.BaseAddress !, new GrpcChannelOptions { HttpClient = httpClient, LoggerFactory = LoggerFactory }); return(channel); }
public static IServiceCollection AddGrpc(this IServiceCollection services, string baseAddress) { services.AddScoped <IAuthenticatedCounterClient, AuthenticatedCounterClient>(); services.AddScoped(services => { // Create a channel with a GrpcWebHandler that is addressed to the backend server. GrpcWebText is used because server streaming requires it. var httpHandler = new GrpcWebHandler(GrpcWebMode.GrpcWebText, new HttpClientHandler()); return(GrpcChannel.ForAddress(baseAddress, new GrpcChannelOptions { HttpHandler = httpHandler })); }); return(services); }
public static void ConfigureServices(IServiceCollection services) { services.AddSingleton(p => { var backendUrl = "https://localhost:5001"; var handler = new GrpcWebHandler(GrpcWebMode.GrpcWebText, new HttpClientHandler()); return(GrpcChannel.ForAddress(backendUrl, new GrpcChannelOptions { HttpHandler = handler })); }); services.AddTransient(p => new TodoActions.TodoActionsClient(p.GetRequiredService <GrpcChannel>())); }
public Task ConnectAsync() { var handler = new HttpClientHandler(); handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; HttpMessageHandler httpMessageHandler = handler; if (_useGrpcWeb != null) { httpMessageHandler = new GrpcWebHandler(_useGrpcWeb.Value, HttpVersion.Version11, httpMessageHandler); } _client = new HttpClient(httpMessageHandler); return(Task.CompletedTask); }
protected HttpClient CreateGrpcWebClient() { var protocol = _endpointName == TestServerEndpointName.Http1 ? new Version(1, 1) : new Version(2, 0); GrpcWebHandler?grpcWebHandler = null; if (_grpcTestMode != GrpcTestMode.Grpc) { var mode = _grpcTestMode == GrpcTestMode.GrpcWeb ? GrpcWebMode.GrpcWeb : GrpcWebMode.GrpcWebText; grpcWebHandler = new GrpcWebHandler(mode, protocol); } return(Fixture.CreateClient(_endpointName, grpcWebHandler)); }
public async Task TestGrpcWebEndpointHttp2() { // GrpcWebText can be used because server streaming requires it. // If server streaming is not used in your app // then GrpcWeb is recommended because it produces smaller messages. var gRpcWebHttpHandler = new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()); var grpcChannel = GrpcChannel.ForAddress("http://localhost:5657", new GrpcChannelOptions { HttpHandler = gRpcWebHttpHandler }); var policyService = grpcChannel.CreateGrpcService <IPolicyService>(); //Act await policyService.GetAllPoliciesAsync(); }
public static async Task Main(string[] args) { var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add <App>("app"); builder.Services.AddSingleton(services => { var httpHandler = new GrpcWebHandler(GrpcWebMode.GrpcWebText, new HttpClientHandler()); return(GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions { HttpHandler = httpHandler })); }); await builder.Build().RunAsync(); }
public static async Task Main(string[] args) { var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add <App>("app"); builder.Services.AddSingleton(services => { var config = services.GetRequiredService <IConfiguration>(); var httpHandler = new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()); return(GrpcChannel.ForAddress(config["ServerEndpoint"], new GrpcChannelOptions { HttpHandler = httpHandler })); }); await builder.Build().RunAsync(); }
public static void Initialize(string address, int delayInMiliseconds = 1000) { GrpcWebHandler handler = new GrpcWebHandler(new HttpClientHandler()); GrpcChannel channel = GrpcChannel.ForAddress(address, new GrpcChannelOptions { HttpClient = new HttpClient(handler) }); Client = new NotificationsGrpc.NotificationsGrpcClient(channel); DelayInMiliseconds = delayInMiliseconds; Subscribe(notification => { Notifications.Add(notification); return(null); }); }
public static void ConfigureServices(IServiceCollection services, string baseUrl, bool isServer) { services.AddScoped <GrpcChannel>(services => { var grpcWebHandler = new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()); if (isServer) { grpcWebHandler.HttpVersion = new Version(1, 1); } var channel = GrpcChannel.ForAddress(baseUrl, new GrpcChannelOptions { HttpHandler = grpcWebHandler }); return(channel); }); }
public static async Task Main(string[] args) { var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add <App>("#app"); builder.Services.AddScoped <GrpcChannel>(services => { var grpcWebHandler = new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()); var channel = GrpcChannel.ForAddress(builder.HostEnvironment.BaseAddress, new GrpcChannelOptions { HttpHandler = grpcWebHandler }); return(channel); }); await builder.Build().RunAsync(); }
public void ConfigureServices(IServiceCollection services) { services.AddGrpc(); //services.AddGrpcClient<GrpcClient>(OnAddGrpcClient); services.AddWebSockets(options => { }); services.AddDbContext <DatabaseContext>(); services.AddSingleton(_ => { var httpHandler = new GrpcWebHandler(GrpcWebMode.GrpcWebText, new HttpClientHandler()); var channel = GrpcChannel.ForAddress("http://localhost:50080/", new GrpcChannelOptions { HttpHandler = httpHandler }); return(new GrpcClient(channel)); }); services.AddSingleton(JsonConvert.DeserializeObject <Option>(File.ReadAllText("config.json"))); services.AddSingleton <DataStore>(); services.AddSingleton <TtsBot>(); services.AddSingleton <WebSocketHandler>(); services.AddCors(OnAddCors); //void OnAddGrpcClient(GrpcClientFactoryOptions options) //{ // options.Address = new Uri("http://localhost:50080/"); //} void OnAddCors(CorsOptions options) => options.AddPolicy("AllowAll", OnAddPolicy); void OnAddPolicy(CorsPolicyBuilder builder) { builder.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader() .WithExposedHeaders("Grpc-Status", "Grpc-Message", "Grpc-Encoding", "Grpc-Accept-Encoding"); } }
public static async Task Main(string[] args) { var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add <App>("app"); builder.Services .AddBlazorise(options => { options.ChangeTextOnKeyPress = true; }) .AddBootstrapProviders() .AddFontAwesomeIcons(); builder.Services.AddSingleton(services => { // Get the service address from appsettings.json var config = services.GetRequiredService <IConfiguration>(); var backendUrl = config["BackendUrl"]; // Create a channel with a GrpcWebHandler that is addressed to the backend server. // // GrpcWebText is used because server streaming requires it. If server streaming is not used in your app // then GrpcWeb is recommended because it produces smaller messages. var httpHandler = new GrpcWebHandler(GrpcWebMode.GrpcWebText, new HttpClientHandler()); return(GrpcChannel.ForAddress(backendUrl, new GrpcChannelOptions { HttpHandler = httpHandler })); }); // HttpClient builder.Services.AddSingleton(new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); var host = builder.Build(); host.Services .UseBootstrapProviders() .UseFontAwesomeIcons(); await host.RunAsync(); }
public Task <ChannelBase> CreateAsync(int id) { if (_channels.TryGetValue(id, out var channel)) { return(Task.FromResult <ChannelBase>(channel)); } var url = _useTls ? "https://" : "http://"; url += _target; var httpClientHandler = new HttpClientHandler(); httpClientHandler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; if (_useClientCertificate) { var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location); var certPath = Path.Combine(basePath !, "Certs", "client.pfx"); var clientCertificate = new X509Certificate2(certPath, "1111"); httpClientHandler.ClientCertificates.Add(clientCertificate); } HttpMessageHandler httpMessageHandler = httpClientHandler; if (_useGrpcWeb != null) { httpMessageHandler = new GrpcWebHandler(_useGrpcWeb.Value, httpMessageHandler) { HttpVersion = HttpVersion.Version11 }; } channel = GrpcChannel.ForAddress(url, new GrpcChannelOptions { HttpClient = new HttpClient(httpMessageHandler) }); _channels[id] = channel; return(Task.FromResult <ChannelBase>(channel)); }
public static async Task Main(string[] args) { GrpcChannel channel = null; CancellationTokenSource cts = new CancellationTokenSource(); var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add <App>("app"); builder.Services.AddSingleton <IDialogService, DialogServiceImplementation>(); builder.Services.AddSingleton <IDialogServiceExt>(services => services.GetService <IDialogService>() as DialogServiceImplementation); builder.Services.AddSingleton <IWebSocketHandler, ClientWebSocketHandler>(); builder.Services.AddSingleton(services => { var httpHandler = new GrpcWebHandler(GrpcWebMode.GrpcWebText, new HttpClientHandler()); channel = GrpcChannel.ForAddress("http://localhost:50080/", new GrpcChannelOptions { HttpHandler = httpHandler }); return(new AdminAccess.AdminAccessClient(channel)); }); builder.Services.AddTransient <IMainViewModel, MainViewModel>(); builder.Services.AddTransient <CreateUserViewModel>(); builder.Services.AddTransient <UsersListViewModel>(); builder.Services.AddTransient <QueueViewModel>(); builder.Services.AddTransient <ItemsViewModel>(); await using WebAssemblyHost host = builder.Build(); _ = (host.Services.GetService <IWebSocketHandler>() as ClientWebSocketHandler).RunAsync(cts.Token); await host.RunAsync(); await channel?.ShutdownAsync(); cts.Cancel(); }
public static async Task Main(string[] args) { var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add <App>("app"); builder.Services.AddSingleton(services => { var handler = new GrpcWebHandler(GrpcWebMode.GrpcWebText, new HttpClientHandler()); var channel = GrpcChannel.ForAddress(services.GetRequiredService <NavigationManager>().BaseUri, new GrpcChannelOptions { HttpClient = new HttpClient(handler) }); // Now we can instantiate gRPC clients for this channel return(new tests.testsClient(channel)); }); await builder.Build().RunAsync(); }
private static void RegisterGrpcWebEndpoint(WebAssemblyHostBuilder builder) { builder.Services.AddSingleton(sp => { var config = sp.GetRequiredService <IConfiguration>(); var grpcEndpointUrl = config["BackendUrl"]; var httpHandler = new GrpcWebHandler(GrpcWebMode.GrpcWebText, new HttpClientHandler()); return(GrpcChannel.ForAddress(grpcEndpointUrl, new GrpcChannelOptions { HttpHandler = httpHandler })); }); builder.Services.AddSingleton(sp => { var service = sp.GetService <GrpcChannel>(); return(new Kanban.KanbanClient(service)); }); }
public static async Task Main(string[] args) { var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add <App>("app"); builder.Services.AddSingleton(x => { var handler = new GrpcWebHandler(GrpcWebMode.GrpcWebText, new HttpClientHandler()); var channel = GrpcChannel.ForAddress("http://localhost:5500", new GrpcChannelOptions { HttpClient = new HttpClient(handler) }); var client = new Billboard.Board.BoardClient(channel); return(client); }); await builder.Build().RunAsync(); }
public static async Task Main(string[] args) { var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add <App>("#app"); builder.Services.AddSingleton(new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); builder.Services.AddSingleton(services => { // Get the service address from appsettings.json var config = services.GetRequiredService <IConfiguration>(); var backendUrl = config["BackendUrl"]; // If no address is set then fallback to the current webpage URL if (string.IsNullOrEmpty(backendUrl)) { var navigationManager = services.GetRequiredService <NavigationManager>(); backendUrl = navigationManager.BaseUri; } var httpHandler = new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()); return(GrpcChannel.ForAddress( backendUrl, new GrpcChannelOptions { HttpHandler = httpHandler })); }); builder.Services.AddTransient <IGrpcWebService>(services => { var grpcChannel = services.GetRequiredService <GrpcChannel>(); return(grpcChannel.CreateGrpcService <IGrpcWebService>()); }); await builder.Build().RunAsync(); }
public static async Task Main(string[] args) { var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add <App>("#app"); builder.Services.AddHttpClient("BlazorWasmGrpcBlog.ServerAPI", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)) .AddHttpMessageHandler <BaseAddressAuthorizationMessageHandler>(); // Supply HttpClient instances that include access tokens when making requests to the server project builder.Services.AddScoped(sp => sp.GetRequiredService <IHttpClientFactory>().CreateClient("BlazorWasmGrpcBlog.ServerAPI")); builder.Services.AddScoped(services => { var configuration = services.GetRequiredService <IConfiguration>(); // Get the service address from appsettings.json var config = services.GetRequiredService <IConfiguration>(); var backendUrl = config["Settings:BackendUrl"]; // If no address is set then fallback to the current webpage URL if (string.IsNullOrEmpty(backendUrl)) { var navigationManager = services.GetRequiredService <NavigationManager>(); backendUrl = navigationManager.BaseUri; } // Create a channel with a GrpcWebHandler that is addressed to the backend server. // // GrpcWebText is used because server streaming requires it. If server streaming is not used in your app // then GrpcWeb is recommended because it produces smaller messages. var httpHandler = new GrpcWebHandler(GrpcWebMode.GrpcWebText, new HttpClientHandler()); return(GrpcChannel.ForAddress(backendUrl, new GrpcChannelOptions { HttpHandler = httpHandler })); }); builder.Services.AddApiAuthorization(); await builder.Build().RunAsync(); }
public async Task SendAsync_GrpcCall_ResponseStreamingPropertySet() { // Arrange var request = new HttpRequestMessage { Version = GrpcWebProtocolConstants.Http2Version, Content = new ByteArrayContent(Array.Empty <byte>()) { Headers = { ContentType = new MediaTypeHeaderValue("application/grpc") } } }; var testHttpHandler = new TestHttpHandler(); var grpcWebHandler = new GrpcWebHandler(GrpcWebMode.GrpcWeb, testHttpHandler); var messageInvoker = new HttpMessageInvoker(grpcWebHandler); // Act await messageInvoker.SendAsync(request, CancellationToken.None); // Assert Assert.AreEqual(true, testHttpHandler.WebAssemblyEnableStreamingResponse); }
private static void RegisterGrpcChannel(IServiceCollection services) { services.AddSingleton(serviceProvider => { var navigationManager = serviceProvider.GetRequiredService <NavigationManager>(); var backendUrl = navigationManager.BaseUri; // GrpcWebText can be used because server streaming requires it. // If server streaming is not used in your app // then GrpcWeb is recommended because it produces smaller messages. var gRpcWebHttpHandler = new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()) { HttpVersion = new Version(1, 1) }; return(GrpcChannel.ForAddress(backendUrl, new GrpcChannelOptions { HttpHandler = gRpcWebHttpHandler })); }); }
public static async Task Main(string[] args) { var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add <App>("app"); //builder.Services.AddTransient(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); builder.Services.AddSingleton(services => { var backendUrl = builder.HostEnvironment.BaseAddress; var httpHandler = new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()); return(GrpcChannel.ForAddress(backendUrl, new GrpcChannelOptions { HttpHandler = httpHandler })); }); await builder.Build().RunAsync(); }