如何解决“Decompressor is not installed for grpc-encoding”问题?

huangapple go评论93阅读模式
英文:

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

问题

当我从Dart调用我的gRPC Golang服务器时,我遇到了以下错误:

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

我已经阅读了https://github.com/bradleyjkemp/grpc-tools/issues/19,但似乎不适用于我的问题。

服务器在Gcloud Ubuntu上运行1.19.2版本。
Dart在Mac Monterey上运行2.18.2版本。

我有一个Dart客户端调用一个Go服务器。两者似乎都使用GZIP进行压缩。

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客户端代码:

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();
}

Go gRPC服务器与Go gRPC客户端和BloomRPC正常工作。

我对gRPC一般不熟悉,对Dart也非常陌生。

提前感谢您解决此问题的任何帮助。

英文:

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 = &quot;proto3&quot;;

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

package helloworld;

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

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

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

GO proto:

syntax = &quot;proto3&quot;;

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

package helloworld;

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

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

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

Dart Client code:

import &#39;package:grpc/grpc.dart&#39;;
import &#39;package:helloworld/src/generated/helloworld.pbgrpc.dart&#39;;

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

  final name = args.isNotEmpty ? args[0] : &#39;world&#39;;

  try {
    final response = await stub.sayHello(
      HelloRequest()..name = name,
      options: CallOptions(compression: const GzipCodec()),
    );
    print(&#39;Greeter client received: ${response.message}&#39;);
  } catch (e) {
    print(&#39;Caught error: $e&#39;);
  }
  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.

答案1

得分: 4

你分享的错误显示你的服务器不支持gzip压缩。

最快的解决方法是在客户端的调用选项中不使用gzip压缩,删除以下行:

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

从你的Dart代码中删除。

go-grpc库在package github.com/grpc/grpc-go/encoding/gzip中实现了gzip压缩编码,但它是实验性的,所以在生产环境中使用它可能不明智;或者至少你应该密切关注它:

// 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.

如果你想在服务器中使用它,你只需要导入该包;该包中没有面向用户的代码:

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

grpc-go的压缩文档将该包作为实现压缩器的示例进行了介绍。

因此,你可能还想将代码复制到一个更稳定的位置,并自行负责维护,直到有一个稳定的支持版本出现。

英文:

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 (
    _ &quot;github.com/grpc/grpc-go/encoding/gzip&quot;
)

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.

huangapple
  • 本文由 发表于 2022年10月14日 07:11:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/74062727.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定