1
votes

Android grpc client is receiving GOAWAY from server with "too many pings" error. Now I realise that this is probably a server side issue, but I think the issue is that the client channel settings do not match that of the servers.

I have a C# gRPC server with the following settings:

List<ChannelOption> channelOptions = new List<ChannelOption>();
channelOptions.Add(new 
ChannelOption("GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS", 
1000));
channelOptions.Add(new 
ChannelOption("GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA", 0));
channelOptions.Add(new 
ChannelOption("GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS", 1));


this.server = new Server(channelOptions) {
    Services = { TerminalService.BindService(this) },
    Ports = {new ServerPort("0.0.0.0", 5000, 
 ServerCredentials.Insecure)}
};

On Android I have the following channel setup:

private val channel = ManagedChannelBuilder.forAddress(name, port)
        .usePlaintext()
        .keepAliveTime(10, TimeUnit.SECONDS)
        .keepAliveWithoutCalls(true)
        .build()

After a few min (however seems to be a random time). I get the goaway error. I noticed that if I stream data on the call then the error never happens. It is only when there is no data on the stream. This leads me to believe the issue is that the GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA needs to be set on the Android client aswell. Problem is for the life of me I cannot find where to set these channel settings on gRPC java. Can someone point out to me where I can set these channel settings? There are no examples where these have been set.

1

1 Answers

0
votes

The channel options being specified are using the wrong names. Names like GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA are the C-defines for things like "grpc.http2.max_pings_without_data".

You can map from the C name to the key string by looking at grpc_types.h. You should prefer using one of the C# constants in ChannelOptions when it is available, but that doesn't seem to be an option in this case.

These options are not visible in the Java ManagedChannelBuilder API because they are server-specific settings. So instead they are visible on the ServerBuilder. See A8 client-side keepalive for reference to the Java keepalive API.