V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
imherer
V2EX  ›  Node.js

nodejs 能动态解析 protobuf 么?

  •  
  •   imherer · 2017-12-15 16:52:21 +08:00 · 4630 次点击
    这是一个创建于 2324 天前的主题,其中的信息可能已经有所发展或是发生改变。

    使用 protobuf 的时候必须得先把.proto 文件定义好,但是很多时候需要解析的数据内容是不确定的,能动态解析么?

    解析库用的是 protobuf.js

    或者有更适合的库?

    第 1 条附言  ·  2017-12-15 17:34:45 +08:00

    假如现在返回的数据如下:

    {
    	"id": 101,
    	"name": "test101"
    }
    

    那么我.proto就会定义成如下格式:

    message textMessage {
        int32 age = 1;
        string name = 2;   
    }
    

    假如某个时候返回的数据变成了如下格式:

    {
    	"id": 101,
    	"name": "test101",
    	"age": 18
    }
    

    那么这个时候.proto就应该变成如下格式:

    message textMessage {
        int32 id = 1;
        string name = 2;
        int32 age = 3;   
    }
    

    这只是简单的情况,复杂的可能还有json嵌套什么的

    初次使用protobuf,还请各位大佬给点建议!

    第 2 条附言  ·  2017-12-15 17:36:04 +08:00
    不好意思,第一个.proto 里的 age 应该是 id 才对,写错了
    24 条回复    2017-12-16 11:15:33 +08:00
    fcten
        1
    fcten  
       2017-12-15 17:17:41 +08:00
    动态解析会影响性能,如果不需要考虑性能的话直接用 json 之类的就行了……
    imherer
        2
    imherer  
    OP
       2017-12-15 17:18:50 +08:00
    @fcten 谢谢。 先说说如何动态解析呢?
    vus520
        3
    vus520  
       2017-12-15 17:22:54 +08:00
    静态语言动态解析 json 也没那么简单吧
    sdrzlyz
        4
    sdrzlyz  
       2017-12-15 17:28:12 +08:00
    protobuf 有 any 跟 oneof。。。
    holyghost
        5
    holyghost  
       2017-12-15 17:28:42 +08:00
    要么 json,要么 https://avro.apache.org/ ,后者有类似于 pb 的版本升级要求。
    binux
        6
    binux  
       2017-12-15 17:29:50 +08:00 via Android
    缺信息,解不了
    imherer
        7
    imherer  
    OP
       2017-12-15 17:35:17 +08:00
    @vus520
    @sdrzlyz
    @holyghost
    @binux
    append 了下,麻烦再看看,谢谢!
    fcten
        8
    fcten  
       2017-12-15 17:35:58 +08:00
    @imherer 你没有明白我的意思,动态解析和 protobuf 设计的初衷不符,所以官方的 protobuf 库都不会支持动态解析的
    当然,可以自己做……但是我觉得不如直接用 json
    imherer
        9
    imherer  
    OP
       2017-12-15 17:37:27 +08:00
    @fcten 嗯,大多数情况下确实先要定义好.proto,但是实际开发中还是有极个别会动态的来使用
    binux
        10
    binux  
       2017-12-15 17:54:44 +08:00 via Android
    protobuf 是向前兼容的啊,直接解析就好了啊。
    虽然 nodejs 是动态语言,但是你为什么要用一个未定义的字段?
    fcten
        11
    fcten  
       2017-12-15 17:57:38 +08:00
    @imherer 既然你解析的数据是 protobuf 格式,那么传给你数据的那一方不是肯定定义了.proto 文件吗,同步一下.proto 文件不就可以了,为什么还要自己写.proto 文件呢
    L3ve
        12
    L3ve  
       2017-12-15 18:00:13 +08:00
    通讯结构应该一早就定好,该怎么样就怎么样,不应该有变化的可能性,要么就是数据结构定义的不好。
    imherer
        13
    imherer  
    OP
       2017-12-15 18:04:02 +08:00
    @L3ve 嗯,理论上是这样的。 但是比如说某一个指令是获取用户背包里的数据的,背包里的数据以 json 的形式存在。不同的用户背包里的数据不一样,这样就牵涉到返回的数据格式有多有少。所以这里就在想能不能动态的解析和转化
    wangxiaoer
        14
    wangxiaoer  
       2017-12-15 18:50:27 +08:00 via Android
    @imherer 背包数据种类也是有限的吧,全部以可选属性加上去不就行了?
    imherer
        15
    imherer  
    OP
       2017-12-15 18:56:45 +08:00
    @wangxiaoer 谢谢,刚用这个不知道有可选属性?我找找文档
    MeteorCat
        16
    MeteorCat  
       2017-12-15 19:27:41 +08:00 via Android
    你需要的是'热更新'?
    imherer
        17
    imherer  
    OP
       2017-12-15 19:30:49 +08:00
    @MeteorCat 不是的,就是数据格式不是很确定
    billwsy
        18
    billwsy  
       2017-12-15 19:33:55 +08:00   ❤️ 1
    proto3 全部是可选,proto2 有 optional 关键字。一般情况下所有字段都应该是 optional 的,以上层约定是不是必选。

    proto2 会写成这个样子:
    message TextMessage {
    optional int32 age = 1;
    optional string name = 2; // Required.
    }

    另外 int32 写成 uint32 更好,如果你在 int32 里面存个-1 那会超级长的。用 uint32 的话可以用 has_age()来判断这个字段是不是存在。
    janxin
        19
    janxin  
       2017-12-15 22:51:25 +08:00 via iPhone
    @imherer 这个是协议设计不合理问题
    bramblex
        20
    bramblex  
       2017-12-15 23:11:31 +08:00
    nodejs 还用什么 protobuf 嘛……

    我们 c 艹的不得不用 protobuf 没办法,你们 nodejs 用是找虐啊……
    panlilu
        21
    panlilu  
       2017-12-15 23:54:50 +08:00
    nodejs 的 protobuf 坑很多,还会导致你 npm install 巨慢,建议谨慎使用。
    jiangzhuo
        22
    jiangzhuo  
       2017-12-15 23:57:25 +08:00
    对于 nodejs 来说动态解析静态解析性能差别不大
    protobuf.js 是最好的了,没有之一,当然还有很多不足比如 OnceOf Any google.protobuf.中的 wellKnownType 不过都可以通过扩展 protobuf.js 轻松实现
    pathbox
        23
    pathbox  
       2017-12-16 10:13:40 +08:00 via iPhone
    protobuf 的初衷不是动态解析吧?
    wucancc
        24
    wucancc  
       2017-12-16 11:15:33 +08:00
    protobuf 的初衷应该是数据压缩吧,目前看是压缩率较高的一种方式。
    有很多 JSON 与 protobuf 互转的 nodejs 库,可以直接使用。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1596 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 17:18 · PVG 01:18 · LAX 10:18 · JFK 13:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.