首页 > 解决方案 > Go gRPC []字节编码/解码

问题描述

我正在开发一组函数(基于 KNative Serving + Eventing),如果是流,我在接收端获取解码数据时遇到很多问题。

因此,我正在实现几个函数,它们将使用 Google API(通过google.golang.org/api/slides/v1)来获取 Google 幻灯片演示文稿(struct来自库),将其编码为 a[]byte并使用 protobuf/gRPC 通过网络发送。这似乎工作正常,但是,当我尝试将其解码回时,Presentation我遇到了错误。打印出Decode调用只返回EOF

这是原型定义:

syntax = "proto3";

package api;

message ParserRequest { 
  bytes Presentation = 1;
}

message ParserResponse {
  int32 Status = 1;
  bytes Document = 2;
}

service ParserService {
// ParsePresentation parse the Google Slides presentation it into the SDR representation
  rpc ParsePresentation(ParserRequest) returns (ParserResponse) {}
}

发送函数类似于:

presentation, err := svc.Presentations.Get(docID).Do()
if err != nil {
    log.Fatalf("Unable to retrieve data from document: %+v", err)
}

if presentation != nil {
    log.Printf("Calling Parser...")

    address := "PORT:IP"
    conn, err := grpc.DialContext(ctx, address, grpc.WithInsecure())
    if err != nil {
        log.Printf("Dial Error! %+v", err)
        return nil, fmt.Errorf("could not connect shipping service: %+v", err)
    }
    defer conn.Close()

    log.Printf("Marshalling data...")
    // data, err := presentation.MarshalJSON()
    // data, err := json.Marshal(presentation)

    var buf bytes.Buffer
    enc := gob.NewEncoder(&buf)
    err = enc.Encode(&presentation)
    if err != nil {
        log.Println("Encode Error: %+v", err)
        log.Fatal("encode error:", err)
    }
    data := buf.Bytes()
    log.Println(data) //[255 211 255 129 3 1 1 12 ...]

    cli, err := parser.NewParserServiceClient(conn).ParsePresentation(ctx, &parser.ParserRequest{Presentation: data})
    if err != nil {
        log.Printf("Cli call Error! %+v", err)
        return nil, fmt.Errorf("failed to get parser service: %+v", err)
    }
    log.Printf("Result: %d", cli.Status)
}

另一方面,我现在应该解码data数组并“翻译”回一个Presentation结构,这样做是通过:

func (c *parserService) ParsePresentation(ctx context.Context, in *pb.ParserRequest) (*pb.ParserResponse, error) {
    log.Printf("ParserService.ParsePresentation was called!")

    if in.Presentation == nil {
        log.Fatalf("Missing parameter Google Slides document.")
    }

    sdrDocument, err := gslides_parser.ParsePresentationBytes(in.Presentation)

    if err != nil {
        log.Fatalf("Unable to parse the Google Slides presentation: %+v", err)
    }

    presentation, err := json.Marshal(sdrDocument)
    return &pb.ParserResponse{Status: 200, Document: presentation}, nil
}

然后,当它到达时gslides_parser.ParsePresentationBytes(in.Presentation)将被解码:

func ParsePresentationBytes(presentationParam []byte) (sdr.Document, error) {

    var (
        document     sdr.Document
        presentation slides.Presentation
    )

    log.Printf("PresentationBytes gob decoder")
    log.Println(presentationParam) // Output: [255 211 255 129 3 1 1 12 ...]
    // err := json.Unmarshal(presentationParam, &presentation)

    buf := bytes.NewBuffer(presentationParam)
    log.Printf("New decoder...")
    dec := gob.NewDecoder(buf)
    log.Printf("Decode...")
    log.Println(&presentation) // Output: &{[]  [] <nil> <nil>   []  {0 map[]} [] []}
    err := dec.Decode(&presentation)
    log.Printf("Done decoding...")

    if err != nil {
        // Never gets here
        document = sdr.Document{}
        (...)
    } else {
        log.Printf("PresentationBytes Error!")
    }

    return document, nil
}

那么,为什么我不能解码信息呢?我看不出这段代码有什么严重的问题,但我也是一个 golang 新手,所以我可能有一些错误让我无法理解。gob 不是处理这个问题的适当方法吗?我尝试简单地编组/解组,但这也会产生错误。

标签: arraysgogoogle-apibytegrpc

解决方案


推荐阅读