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; }
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号