I am using Grpc.Net version : Grpc.AspNetCore 2.27.0
Dot net core version : Asp.Net Core 3.1
Project Sdk for Grpc service ="Microsoft.NET.Sdk.Web"
Project Sdk for Grpc client ="Microsoft.NET.Sdk"
Target framework : netcoreapp 3.1
Grpc.Net.ClientFactory version: 2.27.0
I have created named Grpc client using Grpc.Net.ClientFactory. But, the problem is, Grpc client doesn't wait for the Grpc server to start. I tried with configuring underlying HttpClient's timeout and also RPC call deadline. That is not working. How can I make Grpc client to wait for sometime for Grpc service to start, that could be indeterministic? (may be 10 seconds or 5 minutes waiting) Why deadline setting doesn't work here? What is the RPC deadline, whether it is the waiting time after service gets the request or is it the waiting time including the channel communication to be established? It immediately throws exception. How can I retry async Grpc calls after failure, what is the configuration for it? I am feeling, Grpc.Net.Client is better than client factory as Grpc.Net.Client waits for an infinite duration for Grpc service unless deadline or cancellation token is explicitly mentioned.
Grpc client code:
Program.cs
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
// 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
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
Worker.cs
public class Worker : BackgroundService
{
private readonly Greeter.GreeterClient greeterClient;
private readonly ILogger<Worker> _logger;
public Worker(GrpcClientFactory clientFactory, ILogger<Worker> logger)
{
greeterClient = clientFactory.CreateClient<Greeter.GreeterClient>("greeter-client");
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
var reply = await greeterClient.SayHelloAsync(new HelloRequest { Name = "Greeter client" },
deadline: DateTime.UtcNow.AddSeconds(120));
_logger.LogInformation($"Response from greeter service: {reply.Message}");
}
}
Grpc service code:
public class GreeterService : Greeter.GreeterBase
{
private readonly ILogger<GreeterService> _logger;
public GreeterService(ILogger<GreeterService> logger)
{
_logger = logger;
}
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
{
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
});
}
}
Startup.cs
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddGrpc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGrpcService<GreeterService>();
endpoints.MapGet("/", async context =>
{
await context.Response.WriteAsync("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");
});
});
}
}
Exception details that I am getting:
fail: Grpc.Net.Client.Internal.GrpcCall[6]
Error starting gRPC call.
System.Net.Http.HttpRequestException: No connection could be made because the target machine actively refused it.
---> System.Net.Sockets.SocketException (10061): No connection could be made because the target machine actively refused it.
at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.GetHttp2ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.FinishSendAsyncUnbuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
at Grpc.Net.Client.Internal.GrpcCall`2.RunCall(HttpRequestMessage request)
fail: Grpc.Net.Client.Internal.GrpcCall[3]
Call failed with gRPC error status. Status code: 'Internal', Message: 'Error starting gRPC call: No connection could be made because the target machine actively refused it.'.