【发布时间】:2021-12-26 20:56:55
【问题描述】:
我正在尝试将 Flutter 应用程序连接到 gRPC 服务器。 它曾经在我的旧笔记本电脑上运行良好,但现在当我尝试向端点发出请求时总是出现此错误:
gRPC Error (code: 13, codeName: INTERNAL, message: grpc: error unmarshalling request: string field contains invalid UTF-8, details: [], rawResponse: null)
当我使用另一个 gRPC 客户端时,例如bloomRPC,调用成功并且我得到了正确的数据。 Flutter 应用程序调用甚至没有到达端点服务(我在那里放了一个 println 来测试它,当我从 Flutter 应用程序调用时它不打印任何东西,但在使用bloomRPC 时它确实打印它)。
这是我的客户端连接代码:
class GrpcClient {
late ClientChannel client;
static final GrpcClient _connection = GrpcClient._connect();
factory GrpcClient() => _connection;
GrpcClient._connect(){
client = ClientChannel(
"10.0.2.2",
port: 8080,
options: ChannelOptions(credentials: ChannelCredentials.insecure(), connectionTimeout:Duration(seconds: 10))
);
}
}
我使用GODEBUG=http2debug=2 go run . 运行服务器。当我从 Bloom 拨打电话时,我得到了这个输出:
2021/12/27 22:23:52 http2: Framer 0xc0000a6000: wrote SETTINGS len=6, settings: MAX_FRAME_SIZE=16384
2021/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
2021/12/27 22:23:52 http2: Framer 0xc0000a6000: read WINDOW_UPDATE len=4 (conn) incr=4128769
2021/12/27 22:23:52 http2: Framer 0xc0000a6000: read PING len=8 ping="\x00\x00\x00\x00\x00\x00\x00\x00"
2021/12/27 22:23:52 http2: Framer 0xc0000a6000: wrote SETTINGS flags=ACK len=0
2021/12/27 22:23:52 http2: Framer 0xc0000a6000: read HEADERS flags=END_HEADERS stream=1 len=259
2021/12/27 22:23:52 http2: Framer 0xc0000a6000: wrote PING flags=ACK len=8 ping="\x00\x00\x00\x00\x00\x00\x00\x00"
2021/12/27 22:23:52 http2: decoded hpack field header field ":scheme" = "http"
2021/12/27 22:23:52 http2: decoded hpack field header field ":method" = "POST"
2021/12/27 22:23:52 http2: decoded hpack field header field ":authority" = "localhost:8080"
2021/12/27 22:23:52 http2: decoded hpack field header field ":path" = "/protofiles.UserService/GetUserById"
2021/12/27 22:23:52 http2: decoded hpack field header field "te" = "trailers"
2021/12/27 22:23:52 http2: decoded hpack field header field "content-type" = "application/grpc"
2021/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)"
2021/12/27 22:23:52 http2: decoded hpack field header field "grpc-accept-encoding" = "identity,deflate,gzip"
2021/12/27 22:23:52 http2: decoded hpack field header field "accept-encoding" = "identity,gzip"
2021/12/27 22:23:52 http2: Framer 0xc0000a6000: read WINDOW_UPDATE stream=1 len=4 incr=5
2021/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\"
2021/12/27 22:23:52 http2: Framer 0xc0000a6000: read WINDOW_UPDATE len=4 (conn) incr=5
2021/12/27 22:23:52 http2: Framer 0xc0000a6000: wrote WINDOW_UPDATE len=4 (conn) incr=122
2021/12/27 22:23:52 http2: Framer 0xc0000a6000: wrote PING len=8 ping="\x02\x04\x10\x10\t\x0e\a\a"
2021/12/27 22:23:52 http2: Framer 0xc0000a6000: read PING flags=ACK len=8 ping="\x02\x04\x10\x10\t\x0e\a\a"
2021/12/27 22:23:52 http2: Framer 0xc0000a6000: read SETTINGS flags=ACK len=0
Hello
2021/12/27 22:23:52 http2: Framer 0xc0000a6000: wrote HEADERS flags=END_HEADERS stream=1 len=14
2021/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
2021/12/27 22:23:52 http2: Framer 0xc0000a6000: wrote HEADERS flags=END_STREAM|END_HEADERS stream=1 len=24
还有来自 Dart 应用程序的输出:
2021/12/27 22:25:25 http2: Framer 0xc0002b2000: wrote SETTINGS len=6, settings: MAX_FRAME_SIZE=16384
2021/12/27 22:25:25 http2: Framer 0xc0002b2000: read SETTINGS len=6, settings: ENABLE_PUSH=0
2021/12/27 22:25:25 http2: Framer 0xc0002b2000: wrote SETTINGS flags=ACK len=0
2021/12/27 22:25:25 http2: Framer 0xc0002b2000: read SETTINGS flags=ACK len=0
2021/12/27 22:25:25 http2: Framer 0xc0002b2000: read HEADERS flags=END_HEADERS stream=1 len=169
2021/12/27 22:25:25 http2: decoded hpack field header field ":method" = "POST"
2021/12/27 22:25:25 http2: decoded hpack field header field ":scheme" = "http"
2021/12/27 22:25:25 http2: decoded hpack field header field ":path" = "/protofiles.UserService/GetUserById"
2021/12/27 22:25:25 http2: decoded hpack field header field ":authority" = "10.0.2.2:8080"
2021/12/27 22:25:25 http2: decoded hpack field header field "content-type" = "application/grpc"
2021/12/27 22:25:25 http2: decoded hpack field header field "te" = "trailers"
2021/12/27 22:25:25 http2: decoded hpack field header field "user-agent" = "dart-grpc/2.0.0"
2021/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ɒ\xf1\x01R\b\b\x00\x10\x00\x18\x00 \x00X\x00`\x00h\x00p\x00z\x00"
2021/12/27 22:25:25 http2: Framer 0xc0002b2000: wrote WINDOW_UPDATE len=4 (conn) incr=69
2021/12/27 22:25:25 http2: Framer 0xc0002b2000: wrote PING len=8 ping="\x02\x04\x10\x10\t\x0e\a\a"
2021/12/27 22:25:25 http2: Framer 0xc0002b2000: read DATA flags=END_STREAM stream=1 len=0 data=""
2021/12/27 22:25:25 http2: Framer 0xc0002b2000: wrote HEADERS flags=END_STREAM|END_HEADERS stream=1 len=90
2021/12/27 22:25:25 http2: Framer 0xc0002b2000: read PING flags=ACK len=8 ping="\x02\x04\x10\x10\t\x0e\a\a"
这是原始消息和端点:
message User{
int64 id = 1;
string username = 2;
string auth_user_id = 3;
string email = 4;
string display_name = 5;
Gender gender = 6;
}
func (u *UserService) GetUserById(ctx context.Context, in *protofiles.GetUserRequest) (*protofiles.GetUserResponse, error) {
user, err := u.store.GetByID(in.User.Id)
if err != nil {
return &protofiles.GetUserResponse{}, err
}
return &protofiles.GetUserResponse{User: models.UserHelper.ToProto(user)}, nil
}
【问题讨论】:
-
消息中的某个字符串字段是否可能包含无效的 UTF-8?您是否能够证明使用 Bloom 发送与使用 Flutter 完全相同的消息(我认为 Bloom 使用 NodeJS 运行时而不是 Dart,所以它主要表明另一个 gRPC 客户端可以无错误地提交相同的消息)?是否有可能您正在使用 Dart|Flutter gRPC 的不同发行版|版本?服务器是用什么语言编写的? (它可能有助于在记录收到的消息以帮助诊断方面提供指导)。
-
是的,我在 Bloom 中发送相同的消息,我得到所有有效的 UTF-8。正如我在帖子中提到的,我在服务器函数中添加了一个“prinln”行,以便我可以确保请求到达该函数,但没有打印出任何内容,这意味着该方法甚至没有被调用。
-
服务器是用 Go 编写的。我使用的 Flutter & Dart 版本与我在其他设备上一切正常时使用的版本相同。我无法弄清楚这里到底是什么问题。
-
如果服务器无法解组传入的请求,您的服务器方法将不会被调用。您可以将调试语句添加到您的 Golang 服务器:
GODEBUG=http2debug=2 go run ...以获取传入请求的详细日志记录 -
在您的问题中包含原型和示例消息会对您有所帮助。