10

我正在使用Protobuf.js构建一个节点包,其中包含我们的协议并为该包中定义的 Proto Messages 提供编码和解码功能。我可以使用 .proto 文件(.proto 文件的加载发生在运行时),但是由于模块需要在客户端可用,并且我无法将 .proto 文件打包到解析的 .js 文件中(用browserify构建),我需要使用一种方法,在build.js中启用打包。

输入 JSON 描述符。

var jsonDescriptor = require("./awesome.json"); // exemplary for node

var root = protobuf.Root.fromJSON(jsonDescriptor);

json文件可以打包(browserify解决的需求)。.json 中也可以使用原型类型定义

我将 .proto 文件翻译成 .json 文件,并用我的示例数据进行了尝试。不幸的是,它因重复字段而失败。

.proto 文件看起来像这样:

message Structure {
    map <int32, InnerArray> blocks = 1;
}

message Inner{
    int32 a = 1;
    int32 b = 2;
    bool c = 3;
}

message InnerArray{
    repeated Inner inners = 1;
}   

我翻译成这个 JSON 描述符

{
  "nested": {
    "Structure": {
      "fields": {
        "blocks": {
          "type": "InnerArray",
          "id": 1,
          "map" : true,
          "keyType" : "int32"
        }
      }
    },
    "InnerArray" : {
        "fields": {
            "inners" : {
                "repeated" : true,
                "type" : "Inner",
                "id" : 1
            }
        }
    },
    "Inner" : {
        "fields" : {
            "a" : {
                "type" : "int32",
                "id" : 1
            },
            "b" : {
                "type" : "int32",
                "id" : 2
            },
            "c" : {
                "type" : "bool",
                "id" : 3
            }
        }
    }
  }
}

如果我没记错的话,字段是必需的。

当我对示例数据进行编码和解码时,它会在重复字段处停止:(请注意,地图工作正常)。

{
  "blocks": {
    "0": {
      "inners": {}
    },
    ...

我还检查了我的根目录以了解加载的类型的外观,它看起来与我的定义完全相同,除了重复丢失:

"InnerArray" : {
            "fields": {
                "inners" : {
                    "type" : "Inner",
                    "id" : 1
                }
            }
        },

如何在 JSON 描述符中正确定义重复字段?

如果有一种方法可以预先包含 proto 文件而不是在运行时加载它们,以便我可以用 browserify 将它们包装起来,我也会接受这个作为解决方案。

4

1 回答 1

7

浏览代码后,发现不能在 JSON Descriptor 中设置 required。正确的方法是设置 "rule": "repeated";因为一个字段是用字段描述符设置

于 2017-06-02T12:50:49.540 回答