使用 GRPC-Gateway 进行 HTTP 请求时,流式响应的返回值总是 nil,该如何解决?

使用 GRPC-Gateway 进行 HTTP 请求时,流式响应的返回值总是 nil,该如何解决?

关于 http 请求 grpcgateway stream 流式响应时无法解码返回值

问题:

使用 grpc-gateway 进行 http 请求时的流式响应,使用 runtime.jsonpb.decode 时,得到的返回值都是 nil

解决:

根据推测,该问题可能有以下几个原因造成:

  • grpc-gateway 版本过低:请升级至 grpc-ecosystem/grpc-gateway/v2 v2.4.0。
  • 返回结果中存在多余字段:grpc-gateway 返回的结果中包含了一个额外的 result 字段。请在 proto 文件中添加以下代码:
// 新增 message httpresp {  resp result = 1; }
登录后复制
  • 解码时未使用正确类型:在解码时,请使用 *pb.httpresp 而不是 *pb.resp。

单元测试:

更新代码如下:

package mAIn  import (     "bytes"     "net/http"     "test/pb"     "testing"      "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"     "google.golang.org/grpc" )  func testhttprespstream(t *testing.t) {     url := "http://127.0.0.1:8080/query-stream-resp"     reqdata := &pb.req{id: 1, name: "111"}      var buffer bytes.buffer     encoder := (&runtime.jsonpb{}).newencoder(&buffer)      if err := encoder.encode(reqdata); err != nil {         t.fatal(err)     }      ctx, cancel := context.withcancel(context.background())     defer cancel()     req, err := http.newrequestwithcontext(ctx, http.methodpost, url, &buffer)     if err != nil {         t.fatal(err)     }      resp, err := http.defaultclient.do(req)     if err != nil {         t.fatal(err)     }     defer resp.body.close()      jsonb := new(runtime.jsonpb)     dencoder := jsonb.newdecoder(resp.body)      for {         var result *pb.httpresp // 注意 不要使用 *pb.resp         err := dencoder.decode(&result) // &result           if err == nil {             t.logf("resp: %+v", result)         } else {             t.logf("%+v", err)             break         }     } }
登录后复制

更新 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; }  // 新增 message HttpResp {  Resp result = 1; }  service TestService {     rpc QueryStreamResp(Req) returns (stream HttpResp){         option (google.api.http) = {             post: "/query-stream-resp"             body: "*"         };     };     rpc QueryStreamReq(stream Req) returns (Resp){         option (google.api.http) = {             post: "/query-stream-req"             body: "*"         };     };          rpc Query(stream Req) returns (stream Resp){         option (google.api.http) = {             post: "/query"             body: "*"         };     }; }
登录后复制

更新后,单元测试将能够正确解码流式响应。

© 版权声明
THE END
喜欢就支持一下吧
点赞7 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容