7

我有以下原型:

syntax = "proto3";

import "google/rpc/status.proto";

message Response {   
    google.rpc.Status status = 1;
}

message Request {   
    Type name = 1;
}

service Service {
    rpc SomeMethod (Request) returns (Response);
}

我正在节点中编写一个客户端:

    const path = require('path');
    const grpc = require('grpc');
    const protoLoader = require('@grpc/proto-loader');
    const protoFiles = require('google-proto-files');

    const PROTO_PATH = path.join(__dirname, '/proto/myproto.proto');

    const packageDefinition = protoLoader.loadSync(
      PROTO_PATH,
      {
        keepCase: true,
        longs: String,
        enums: String,
        defaults: true,
        oneofs: true,
        includeDirs: [protoFiles('rpc')],
      },
    );

    const proto = grpc.loadPackageDefinition(packageDefinition);
    const client = new proto.Service('localhost:1111', grpc.credentials.createInsecure());

当我运行客户端时,我收到以下错误:TypeError: proto.Service is not a constructor。我发现它与status.proto的导入有关。使用 proto-loader 导入 google protos 的正确方法是什么?服务器使用 Java。

4

2 回答 2

8

Olga,如果您使用的是 includeDirs,则不能在 PROTO_PATH 中使用绝对路径。显然,您需要将两个路径(即 myproto.proto 的路径和 google-proto-files 的路径)都放入 includeDirs 并仅使用文件名作为 PROTO_PATH ,然后它就可以正常工作了。看这里:

https://github.com/grpc/grpc-node/issues/470

这是修改后的代码。请注意,我还必须在 myproto.proto 中将“Type”替换为“int32”。

const path = require('path');
const grpc = require('grpc');
const protoLoader = require('@grpc/proto-loader');
const protoFiles = require('google-proto-files');

const PROTO_PATH = 'myproto.proto';

const packageDefinition = protoLoader.loadSync(
  PROTO_PATH,
  {
    keepCase: true,
    longs: String,
    enums: String,
    defaults: true,
    oneofs: true,
    includeDirs: ['node_modules/google-proto-files', 'proto']
    },
  );

const protoDescriptor = grpc.loadPackageDefinition(packageDefinition);
const client = new protoDescriptor.Service('localhost:1111',  grpc.credentials.createInsecure());

希望能帮助到你。:)

于 2018-10-16T18:24:39.927 回答
0

这里的问题是protoFiles('rpc')返回的路径不适import用于文件中的行.proto。该导入行意味着它@grpc/proto-loader正在寻找一个包含的包含目录google/rpc/status.proto,但protoFiles('rpc')返回一个直接包含的目录status.proto。因此,您必须更改其中一项或两项,以便相关目录正确匹配。

于 2018-10-15T15:58:18.717 回答