Home > Software engineering >  How do I resolve the "Decompressor is not installed for grpc-encoding" issue?
How do I resolve the "Decompressor is not installed for grpc-encoding" issue?

Time:10-15

I'm getting this error when I call my gRPC Golang server from Dart:

Caught error: gRPC Error (code: 12, codeName: UNIMPLEMENTED, message: grpc: Decompressor is not installed for grpc-encoding "gzip", details: [], rawResponse: null, trailers: {})

I have read https://github.com/bradleyjkemp/grpc-tools/issues/19, and it doesn't appear to apply to my issue.

The server is running 1.19.2 on Gcloud Ubuntu. Dart is running 2.18.2 on Mac Monterey

I have a Dart client calling a Go server. Both appear to be using GZIP for compression.

Dart proto

syntax = "proto3";

option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";
option objc_class_prefix = "HLW";

package helloworld;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}

GO proto:

syntax = "proto3";

option go_package = "google.golang.org/grpc/examples/helloworld/helloworld";
option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";

package helloworld;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}

Dart Client code:

import 'package:grpc/grpc.dart';
import 'package:helloworld/src/generated/helloworld.pbgrpc.dart';

Future<void> main(List<String> args) async {
  final channel = ClientChannel(
    'ps-dev1.savup.com',
    port: 54320,
    options: ChannelOptions(
      credentials: ChannelCredentials.insecure(),
      codecRegistry:
          CodecRegistry(codecs: const [GzipCodec(), IdentityCodec()]),
    ),
  );
  final stub = GreeterClient(channel);

  final name = args.isNotEmpty ? args[0] : 'world';

  try {
    final response = await stub.sayHello(
      HelloRequest()..name = name,
      options: CallOptions(compression: const GzipCodec()),
    );
    print('Greeter client received: ${response.message}');
  } catch (e) {
    print('Caught error: $e');
  }
  await channel.shutdown();
}

The Go gRPC server works fine with a Go gRPC client and BloomRPC.

I'm new to gRPC in general and very new to Dart.

Thanks in advance for any help resolving this issue.

CodePudding user response:

That error that you shared shows that your server doesn't support gzip compression.

The quickest fix is to not use gzip compression in the client's call options, by removing the line:

options: CallOptions(compression: const GzipCodec()),

from your Dart code.

The go-grpc library has an implementation of a gzip compression encoding in package github.com/grpc/grpc-go/encoding/gzip, but it's experimental, so likely not wise to use it in production; or at least you should pay close attention to it:

// Package gzip implements and registers the gzip compressor
// during the initialization.
//
// Experimental
//
// Notice: This package is EXPERIMENTAL and may be changed or removed in a
// later release.

If you want to use it in your server, you just need to import the package; there is no user-facing code in the package:

import (
    _ "github.com/grpc/grpc-go/encoding/gzip"
)

The documentation about compression for grpc-go mentions this above package as an example of how your implement such a compressor.

So you may also want to copy the code to a more stable location and take responsibility for maintaining it yourself, until there is a stable supported version of it.

  • Related