如何使用 grpc/proto-loader 在 NestJS 中接收“any”?

问题描述 投票:0回答:1

我正在使用 NestJS,并且在我的 protobuf 文件中有以下消息:

message MyMessage {
    string test = 1;
    google.protobuf.Any payload = 2;
}

然后我使用具有以下配置的 NestJS 作为服务器:

const grpcApp = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
    transport: Transport.GRPC,
    options: {
      package: 'mypackage',
      protoPath: './myfile.proto',
      url: 'localhost:5000',
      loader: {
        json: true
      }
    },
  });

我在Typescript中也有MyMessage的定义如下:

export class MyMessage {
    test: string
    payload: any
}

我正在将收到的消息记录到控制台,我的问题是,无论我在

payload
中发送什么内容,我总是收到一个空对象,例如
{ test: 'ttt', payload: {} }

据我了解,grpc/proto-loader 不支持 google.protobuf.Any。 但是,根据 https://github.com/grpc/grpc-node/blob/master/packages/proto-loader/README.md ,如果我将 json 设置为 true 我应该能够克服这个问题。 不幸的是,无论

json: true
是否设置,有效负载仍然是空的。

我是GRPC新手,似乎在兜圈子,请帮忙。

nestjs protocol-buffers grpc grpc-node
1个回答
0
投票

我修改了你的 Protobuf 文件,因为它缺少

syntax
service
定义

myfile.proto

syntax = "proto3";

import "google/protobuf/any.proto";

service MyService {
    rpc MyMethod(MyMessage) returns (MyMessage) {}
}

message MyMessage {
    string test = 1;
    google.protobuf.Any payload = 2;
}

我使用了以下非常基本的 Node.JS 服务器实现:

index.js

const PROTO_PATH = __dirname + "/myfile.proto";

const grpc = require("@grpc/grpc-js");
const protoLoader = require("@grpc/proto-loader");

var packageDefinition = protoLoader.loadSync(
    PROTO_PATH, {
        keepCase: true,
        longs: String,
        enums: String,
        defaults: true,
        oneofs: true
    });

const protoDescriptor = grpc.loadPackageDefinition(packageDefinition);

// Provide an implementation (echo) for the RPC method
const myMethod = (m) => {
    return m;
};

const server = new grpc.Server();
server.addService(protoDescriptor.MyService.service, {
    myMethod: (call, callback) => {
        // Log the request
        console.log(call.request);
        // Invoke the implementation
        callback(null, myMethod(call.request));
    }
});
server.bindAsync("0.0.0.0:50051", grpc.ServerCredentials.createInsecure(), () => {
    server.start();
});

我是gRPCurl

的支持者

data.json

{
  "test":"Freddie",
  "payload":{
    "@type":"type.googleapis.com/google.protobuf.StringValue",
    "value":"Freddie"
  }
}
cat data.json \
| grpcurl \
  -plaintext \
  -proto protos/myfile.proto \
  -d @ \
  localhost:50051 \
  MyService/MyMethod
{
  "test": "Freddie",
  "payload": {
    "@type": "type.googleapis.com/google.protobuf.StringValue",
    "value": "Freddie"
  }
}
And the server logs:

```console
{
  test: 'Freddie',
  payload: {
    type_url: 'type.googleapis.com/google.protobuf.StringValue',
    value: <Buffer 0a 07 46 72 65 64 64 69 65>
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.