Hi,
We have a gRPC client and server where the server is capable of sending
binary data ranging from 100 MB to 5 gig based on the client request.
Maximum chunk size is 512 MB, meaning data above 512 is chunked and
streamed. For eg: if it is 1000 MB, it will be streamed as 512 MB and 488
MB.
We have decided to test the impact of introducing compression and facing
some issues in getting it done.
Application and hosting details
gRPC Server with ASP.NET Core
Hosting and dev Environment
- *Framework*: ASP.NET Core (C#)
- *Server*: Kestrel (built-in web server for ASP.NET Core)
- *Protocol*: HTTP/2 (required for gRPC)
- goog_1490578365*Security*: HTTPS with TLS (certificate-based
encryption)
- <TargetFramework>net8.0</TargetFramework>
- <PackageReference Include="Grpc.AspNetCore" Version="2.54.0" />
Problem Statement:
The issue began when we observed that even though the gRPC client sends the
grpc-accept-encoding: identity,gzip header (confirmed via logs), the server
logs still reported:
Client supports response compression: none
Current Implementation:
Server side:
builder.Services.AddGrpc(options =>
{
options.MaxReceiveMessageSize = int.MaxValue;
options.MaxSendMessageSize = int.MaxValue;
if (useCompression)
{
options.ResponseCompressionAlgorithm = "gzip";
options.ResponseCompressionLevel = CompressionLevel.Fastest;
//Register compression provider
options.CompressionProviders = new
List<Grpc.Net.Compression.ICompressionProvider>
{
new
Grpc.Net.Compression.GzipCompressionProvider(System.IO.Compression.CompressionLevel.Fastest)
};
options.Interceptors.Add<CompressionLoggingInterceptor>();
}
});
Client Side:
var compressionProviders = new List<ICompressionProvider>
{
new GzipCompressionProvider(CompressionLevel.Fastest)
};
if (!useTls)
{
var handler = new SocketsHttpHandler();
handler.EnableMultipleHttp2Connections = true;
var loggingHandler = new LoggingHandler(handler);
var channelOptions = new GrpcChannelOptions
{
HttpHandler = loggingHandler,
MaxReceiveMessageSize = int.MaxValue,
CompressionProviders = compressionProviders
};
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport",
true);
//channelOptions.HttpHandler = new HttpClientHandler();
return GrpcChannel.ForAddress(address, channelOptions);
}
What Theory Says – If compression is enabled during channel creation, the
client will send header compression header (grpc-accept-encoding:
identity,gzip) and server can will decide on this. Here only the server
response will be compressed, not the client and that is we are trying to
attain.
But the server log says "Client supports response compression: none"
A detailed search on it suggested explicitly requesting compression per
message, but both of the below options were not usable with the project
setup.
var callOptions = new CallOptions()
.WithWriteOptions(new WriteOptions(WriteFlags.UseCompression)); Note:
this is to explicitly set compression request per message.
var response = await client.MyRpcMethodAsync(new MyRequest(), callOptions);
But we cannot use WriteFlags.UseCompression in ASP.NET core and
Grpc.Net.Client
OR
var callOptions = Grpc.Net.Client.GrpcCallOptionsExtensions.WithCompression(new
CallOptions(), "gzip");
using var call = client.RequestData(request, callOptions);
Both of them were not available.
What we are looking for.
A solution to tackle the issue or sample compression implementation using
gRPC and ASP.NET core
--
You received this message because you are subscribed to the Google Groups
"grpc.io" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/grpc-io/f7d03da9-e3f8-4f56-afc2-d8923247fea5n%40googlegroups.com.