当我从 Flutter 应用程序向 gRPC 端点发出请求时,出现 gRPC Invalid UTF-8

Ali*_*jji 3 grpc flutter grpc-dart

我正在尝试将 Flutter 应用程序连接到 gRPC 服务器。\n它过去在我的旧笔记本电脑上运行良好,但现在当我尝试向端点发出请求时总是收到此错误:

\n
gRPC Error (code: 13, codeName: INTERNAL, message: grpc: error unmarshalling request: string field contains invalid UTF-8, details: [], rawResponse: null)\n
Run Code Online (Sandbox Code Playgroud)\n

当我使用另一个gRPC客户端(例如bloomRPC)时,调用成功并且我得到了正确的数据。\nFlutter应用程序调用甚至没有到达端点服务(我在那里放了一个println来测试它,它没有打印任何内容)当我从 Flutter 应用程序进行调用时,但在使用bloomRPC 时它确实会打印它)。

\n

这是我的客户端连接代码:

\n
class GrpcClient {\n  late ClientChannel client;\n  static final GrpcClient _connection = GrpcClient._connect();\n\n  factory GrpcClient() => _connection;\n  \n  GrpcClient._connect(){\n    client = ClientChannel(\n     "10.0.2.2",\n      port: 8080,\n      options: ChannelOptions(credentials: ChannelCredentials.insecure(), connectionTimeout:Duration(seconds: 10))\n    );\n\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我用 运行服务器 GODEBUG=http2debug=2 go run .。当我从 Bloom 拨打电话时得到以下输出:

\n
2021/12/27 22:23:52 http2: Framer 0xc0000a6000: wrote SETTINGS len=6, settings: MAX_FRAME_SIZE=16384\n2021/12/27 22:23:52 http2: Framer 0xc0000a6000: read SETTINGS len=36, settings: ENABLE_PUSH=0, MAX_CONCURRENT_STREAMS=0, INITIAL_WINDOW_SIZE=4194304, MAX_FRAME_SIZE=4194304, MAX_HEADER_LIST_SIZE=8192, UNKNOWN_SETTING_65027=1\n2021/12/27 22:23:52 http2: Framer 0xc0000a6000: read WINDOW_UPDATE len=4 (conn) incr=4128769\n2021/12/27 22:23:52 http2: Framer 0xc0000a6000: read PING len=8 ping="\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00"\n2021/12/27 22:23:52 http2: Framer 0xc0000a6000: wrote SETTINGS flags=ACK len=0\n2021/12/27 22:23:52 http2: Framer 0xc0000a6000: read HEADERS flags=END_HEADERS stream=1 len=259\n2021/12/27 22:23:52 http2: Framer 0xc0000a6000: wrote PING flags=ACK len=8 ping="\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00"\n2021/12/27 22:23:52 http2: decoded hpack field header field ":scheme" = "http"\n2021/12/27 22:23:52 http2: decoded hpack field header field ":method" = "POST"\n2021/12/27 22:23:52 http2: decoded hpack field header field ":authority" = "localhost:8080"\n2021/12/27 22:23:52 http2: decoded hpack field header field ":path" = "/protofiles.UserService/GetUserById"\n2021/12/27 22:23:52 http2: decoded hpack field header field "te" = "trailers"\n2021/12/27 22:23:52 http2: decoded hpack field header field "content-type" = "application/grpc"\n2021/12/27 22:23:52 http2: decoded hpack field header field "user-agent" = "grpc-node/1.24.7 grpc-c/8.0.0 (windows; chttp2; ganges)"\n2021/12/27 22:23:52 http2: decoded hpack field header field "grpc-accept-encoding" = "identity,deflate,gzip"\n2021/12/27 22:23:52 http2: decoded hpack field header field "accept-encoding" = "identity,gzip"\n2021/12/27 22:23:52 http2: Framer 0xc0000a6000: read WINDOW_UPDATE stream=1 len=4 incr=5\n2021/12/27 22:23:52 http2: Framer 0xc0000a6000: read DATA flags=END_STREAM stream=1 len=122 data="\\x00\\x00\\x00\\x00u\\ns\\b\\x05\\x12\\x05Hello\\x1a$1bcc4186-3a63-4a22-8dac-c144d6d0eb49\\"\\x05Hello*\\x05Hello0\\x00:\\x04\\b\\x14\\x10\\nB\\x05HelloJ\\x05HelloR\\x04\\b\\x14\\x10\\nZ\\b\\b\\x14\\x10\\x01\\x18\\x01 \\x00`\\x14h\\x14p\\x14x\\x14\\x82\\x01\\"\n2021/12/27 22:23:52 http2: Framer 0xc0000a6000: read WINDOW_UPDATE len=4 (conn) incr=5\n2021/12/27 22:23:52 http2: Framer 0xc0000a6000: wrote WINDOW_UPDATE len=4 (conn) incr=122\n2021/12/27 22:23:52 http2: Framer 0xc0000a6000: wrote PING len=8 ping="\\x02\\x04\\x10\\x10\\t\\x0e\\a\\a"\n2021/12/27 22:23:52 http2: Framer 0xc0000a6000: read PING flags=ACK len=8 ping="\\x02\\x04\\x10\\x10\\t\\x0e\\a\\a"\n2021/12/27 22:23:52 http2: Framer 0xc0000a6000: read SETTINGS flags=ACK len=0\nHello\n2021/12/27 22:23:52 http2: Framer 0xc0000a6000: wrote HEADERS flags=END_HEADERS stream=1 len=14\n2021/12/27 22:23:52 http2: Framer 0xc0000a6000: wrote DATA stream=1 len=192 data="\\x00\\x00\\x00\\x00\\xbb\\n\\xb8\\x01\\b\\x05\\x12\\tHajjivsky\n2021/12/27 22:23:52 http2: Framer 0xc0000a6000: wrote HEADERS flags=END_STREAM|END_HEADERS stream=1 len=24\n
Run Code Online (Sandbox Code Playgroud)\n

Dart 应用程序的输出如下:

\n
2021/12/27 22:25:25 http2: Framer 0xc0002b2000: wrote SETTINGS len=6, settings: MAX_FRAME_SIZE=16384\n2021/12/27 22:25:25 http2: Framer 0xc0002b2000: read SETTINGS len=6, settings: ENABLE_PUSH=0\n2021/12/27 22:25:25 http2: Framer 0xc0002b2000: wrote SETTINGS flags=ACK len=0\n2021/12/27 22:25:25 http2: Framer 0xc0002b2000: read SETTINGS flags=ACK len=0\n2021/12/27 22:25:25 http2: Framer 0xc0002b2000: read HEADERS flags=END_HEADERS stream=1 len=169\n2021/12/27 22:25:25 http2: decoded hpack field header field ":method" = "POST"\n2021/12/27 22:25:25 http2: decoded hpack field header field ":scheme" = "http"\n2021/12/27 22:25:25 http2: decoded hpack field header field ":path" = "/protofiles.UserService/GetUserById"\n2021/12/27 22:25:25 http2: decoded hpack field header field ":authority" = "10.0.2.2:8080"\n2021/12/27 22:25:25 http2: decoded hpack field header field "content-type" = "application/grpc"\n2021/12/27 22:25:25 http2: decoded hpack field header field "te" = "trailers"\n2021/12/27 22:25:25 http2: decoded hpack field header field "user-agent" = "dart-grpc/2.0.0"\n2021/12/27 22:25:25 http2: Framer 0xc0002b2000: read DATA stream=1 len=69 data="\\x00\\x00\\x00\\x00@\\n>\\b\\x05\\x12\\x00\\x1a\\x00\\"\\x00(\\x002\\f\\b\\xa4\\xa6\\xa8\\x8e\\x06\\x10\\xa0\\xb7\\x93\\xf1\\x01:\\x00B\\x00J\\f\\b\\xa4\\xa6\\xa8\\x8e\\x06\\x10\\xf0\xc9\x92\\xf1\\x01R\\b\\b\\x00\\x10\\x00\\x18\\x00 \\x00X\\x00`\\x00h\\x00p\\x00z\\x00"\n2021/12/27 22:25:25 http2: Framer 0xc0002b2000: wrote WINDOW_UPDATE len=4 (conn) incr=69\n2021/12/27 22:25:25 http2: Framer 0xc0002b2000: wrote PING len=8 ping="\\x02\\x04\\x10\\x10\\t\\x0e\\a\\a"\n2021/12/27 22:25:25 http2: Framer 0xc0002b2000: read DATA flags=END_STREAM stream=1 len=0 data=""\n2021/12/27 22:25:25 http2: Framer 0xc0002b2000: wrote HEADERS flags=END_STREAM|END_HEADERS stream=1 len=90\n2021/12/27 22:25:25 http2: Framer 0xc0002b2000: read PING flags=ACK len=8 ping="\\x02\\x04\\x10\\x10\\t\\x0e\\a\\a"\n
Run Code Online (Sandbox Code Playgroud)\n

这是原始消息和端点:

\n
message User{\n    int64 id = 1;\n    string username = 2;\n    string auth_user_id = 3;\n    string email = 4;\n    string display_name = 5;\n    Gender gender = 6;\n}\n
Run Code Online (Sandbox Code Playgroud)\n
func (u *UserService) GetUserById(ctx context.Context, in *protofiles.GetUserRequest) (*protofiles.GetUserResponse, error) {\n    user, err := u.store.GetByID(in.User.Id)\n    if err != nil {\n        return &protofiles.GetUserResponse{}, err\n    }\n    return &protofiles.GetUserResponse{User: models.UserHelper.ToProto(user)}, nil\n}\n
Run Code Online (Sandbox Code Playgroud)\n

Ali*_*jji 7

经过几个小时的反复试验,我终于弄清楚了问题所在,就像许多其他错误一样,它被证明是一个愚蠢的错误。原始文件消息中的标签顺序已更改(在顶部添加了一个新字段,所有其他字段均向下推)。服务器使用新定义,而客户端使用旧定义。当客户端尝试调用端点时,标签不匹配。

我所要做的就是重新生成客户端存根的文件。