I'm using the gRPC client in C# and using a long-lived duplex stream. However, the TCP connection is closed at some time and therefore I would like to use a keepalive in the client. The server (written in Go) is already configured correctly for the keepalive and already tested with clients written in Go.
I use the following code to set a keepalive for 5 minutes and also to enable tracing for viewing all incoming/outgoing bytes.
Environment.SetEnvironmentVariable("GRPC_TRACE", "tcp,channel,http,secure_endpoint");
Environment.SetEnvironmentVariable("GRPC_VERBOSITY", "DEBUG");
var callCredentials = CallCredentials.FromInterceptor(Interceptor());
var roots = Encoding.UTF8.GetString(Resources.roots);
Channel = new Channel(address, ChannelCredentials.Create(new SslCredentials(roots), callCredentials), new[]
{
new ChannelOption("grpc.keepalive_time_ms", 5 * 60 * 1000), // 5 minutes
});
await Channel.ConnectAsync(DateTime.UtcNow.AddSeconds(5));
However, in the log there are no bytes sent at 5 minutes and the connection is closed as I can no longer send/receive messages via the same stream after the stream has been idle for some time.
How would I properly enable keepalive?
The keepalive ping is a way to check if a channel is currently working by sending HTTP2 pings over the transport. It is sent periodically, and if the ping is not acknowledged by the peer within a certain timeout period, the transport is disconnected.
A gRPC channel uses a single HTTP/2 connection, and concurrent calls are multiplexed on that connection. When the number of active calls reaches the connection stream limit, additional calls are queued in the client.
gRPC connections are persistent, so a single client will always talk to a single backend in that configuration. It's fine if you have lots of clients but can easily lead to load imbalances.
A gRPC channel provides a connection to a gRPC server on a specified host and port. It is used when creating a client stub. Clients can specify channel arguments to modify gRPC's default behavior, such as switching message compression on or off. A channel has state, including connected and idle .
try add the following ChannelOption in the client.
new ChannelOption("grpc.keepalive_permit_without_calls", 1)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With