
Grpc-gateway流式HTTP响应解码故障排查与修复指南
在使用grpc-gateway将gRPC服务转换为HTTP服务时,处理流式HTTP响应经常会遇到解码失败的问题。本文将分析一个典型的案例,并提供相应的解决方案。
问题描述: 客户端通过HTTP请求调用gRPC服务的流式响应方法,服务器端已正确返回JSON格式的流式数据,但客户端使用runtime.jsonpb.Decode解码时,却始终得到nil值。服务器端日志显示响应数据正确:
{"result":{"code":1,"msg":"1111"}}
{"result":{"code":2,"msg":"2222"}}
{"result":{"code":3,"msg":"3333"}}
{"result":{"code":4,"msg":"4444"}}
{"result":{"code":5,"msg":"5555"}}
{"result":{"code":6,"msg":"6666"}}客户端解码结果为nil,表明解码过程存在问题。
相关代码片段:
proto文件 (./pb/test.proto):
syntax = "proto3";
package pb;
option go_package = "/pb;pb";
import "google/api/annotations.proto";
message Req {
int32 id = 1;
string name = 2;
}
message Resp {
int32 code = 1;
string msg = 2;
}
service TestService {
rpc QueryStreamResp(Req) returns (stream Resp) {
option (google.api.http) = {
post: "/query-stream-resp"
body: "*"
};
};
}gRPC服务端代码 (Go):
func (ts *TestService) QueryStreamResp(req *pb.Req, stream pb.TestService_QueryStreamRespServer) error {
// ... 服务端逻辑 ...
for _, r := range result {
log.Printf("resp: %+v", r)
if err := stream.Send(r); err != nil {
log.Fatal(err)
}
time.Sleep(100 * time.Millisecond)
}
// ... 服务端逻辑 ...
return nil
}单元测试代码 (Go):
func TestHttpRespStream(t *testing.T) {
// ... 测试代码 ...
jsonb := &runtime.JSONPb{}
decoder := jsonb.NewDecoder(resp.Body)
for {
var result *pb.Resp
err := decoder.Decode(result)
// ... 测试代码 ...
}
}问题解决:
问题根源在于:
grpc-gateway版本过低: 建议升级到最新版本的github.com/grpc-ecosystem/grpc-gateway/v2。
响应结构不匹配: grpc-gateway返回的JSON数据包含额外的result字段。需要在proto文件中定义匹配的message:
message HttpResp {
Resp result = 1;
}*pb.HttpResp作为目标类型,并使用&result传递解码目标的地址。修改后的单元测试代码:var result *pb.HttpResp err := decoder.Decode(&result)
通过以上三点修改,解码问题即可解决,单元测试将正确打印每个流式响应数据。
以上就是Grpc-gateway流式HTTP响应解码失败:如何排查并解决runtime.JSONPb.Decode返回nil值的问题?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号