V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
YORYOR
V2EX  ›  程序员

求一个关于 protobuffer 项目的解决方案

  •  
  •   YORYOR · 2014-11-20 16:27:13 +08:00 · 3363 次点击
    这是一个创建于 3443 天前的主题,其中的信息可能已经有所发展或是发生改变。
    求解答:
    我们现在有这样一个问题,client 和server 都依赖同一批proto文件,client用java实现,server用c++实现,现在想把这写proto文件以及proto文件生成的代码作成一个公共的项目,让client和server来依赖这个项目,那么问题来了,java可以通过pom搞定,c++那边怎么整,有解决方法吗,,多谢
    14 条回复    2014-11-28 18:46:49 +08:00
    c4pt0r
        1
    c4pt0r  
       2014-11-20 16:42:17 +08:00
    没懂,用 pom 干嘛, git submodule 不就行了吗
    damngood
        2
    damngood  
       2014-11-20 16:57:29 +08:00
    现在做的项目客户端 C#, 服务端 Golang 共用一个 proto 文件.
    我在服务端写了个脚本, 一旦发现有变化自动运行 protoc

    c++ 不也应该差不多的么. 一旦有变化 regenerate, 然后 rebuild.
    yuankui
        3
    yuankui  
       2014-11-20 17:24:11 +08:00
    你把生成的文件弄进vcs,那不是恶心人吗?
    YORYOR
        4
    YORYOR  
    OP
       2014-11-20 18:29:20 +08:00
    @c4pt0r 正在尝试。

    @yuankui 生成要使用的java文件哪恶心到人了
    benjiam
        5
    benjiam  
       2014-11-20 18:57:03 +08:00 via Android
    proto的传输格式是什么样子的?转成string 再加个长度 type然后传吗
    goofansu
        6
    goofansu  
       2014-11-20 19:34:40 +08:00
    @YORYOR 生成的文件一般是不进版本控制的,应该是测试的时候build出来
    rrfeng
        7
    rrfeng  
       2014-11-20 19:52:30 +08:00
    同意楼上。vcs 里只放 proto 文件就好了。项目 build 的时候生成各自的程序。
    yueyoum
        8
    yueyoum  
       2014-11-21 10:28:30 +08:00
    我的用法是 一个单独的 git repo, 放 protobuf 定义

    然后 server 和 client 的 仓库 都去添加那个 protobuf 的仓库为 submodule

    当 protobuf修改 提交后 , server 和 client 都 git submodule update 一下,
    最后各自生产各自的代码就行
    yueyoum
        9
    yueyoum  
       2014-11-21 10:28:58 +08:00
    @damngood 一看就是做手游的吧, unity3d, golang server ?
    damngood
        10
    damngood  
       2014-11-21 11:08:48 +08:00
    @yueyoum 恩, 是的
    yueyoum
        11
    yueyoum  
       2014-11-21 11:36:35 +08:00   ❤️ 1
    刚好我今早还想到 要自己做一个轮子,
    因为 protobuffer 岁好,但是 在erlang中使用起来确实麻烦,
    如果自己定义 消息的二进制结构,那么每个消息服务端和客户端都要自己去 pack/unpack,
    比protobuf这种麻烦多了,

    于是便有了这个想法:
    用python写protocol定义, 然后生成对应语言的操作代码
    生成的代码直接去 pack/unpack 二进制数据。

    这样 protocol 定义写起来非常方便,而且自动生成各种语言的代码,
    方便,省事,而且为了简单轻量:

    可能有以下特性:

    1. 不做错误检查, pack进去的数据由 人保证不写错, 否则在 serialize 的可能会报错
    2. 生成的代码,没有压缩算法,一个 32位整数,哪怕你之填充了一个1, 那么也是老老实实的占用4个字节。
    3. 保持简单,生成的二进制结构就是这么的stupid:

    Binary:
    [4 bytes length][ * body *]
    Body:
    [4 bytes protocol id][ * data *]
    Data:
    [1 byte date type sign number][ * value * ]...
    [1 byte date type sign number][4 bytes string length][* string value *]...
    [1 byte date type sign number][4 bytes repeated amount][* repeated value *]...
    Repated Value:
    [1 byte date type sign number][* value *]...




    比如举个例子:
    协议定义

    class Weapon(EmbeddedProtocol):
    ----id = IntegerField(bytes=4)
    ----attack = FloatField()

    @Spec(protocol_id=10) # 协议号
    class Person(Protocol):
    ----id = IntegerField(bytes=8) # 64 bits integer
    ----gender = IntegerField(bytes=1) # 8 bits integer
    ----name = StringField()
    ----position = PointField()
    ----weapons = ListField(Weapon)


    然后用python直接生产对应语言的 代码。
    python例子(以及所有支持OOP的语言),生成后的代码使用起来类似这样:

    p = Person()
    p.id = 1
    p.gender = 1
    p.name = "My Name"
    p.position = (23, 56)
    p.weapons.extend([
    ----Weapon(id=11, attack=99),
    ----Weapon(id=12, attack=101),
    ])

    binary = p.Serialize()


    erlang 例子,生成后的代码使用类似这样:

    P = person:new(),
    P1 = person:set(P, id, 1),
    P2 = person:set(P1, gender, 1),
    %% 或者一次设置多个Field
    P3 = P2#person(name=<<"My Name">>, position=[23, 56]),

    W1 = weapon:new(#weapon(id=11, attack=99)),
    W2 = weapon:new(#weapon(id=12, attack=101)),


    P4 = person:append_to_field(P3, weapons, [W1, W2])

    Binary = person:serialize(P4)
    yueyoum
        12
    yueyoum  
       2014-11-21 11:37:31 +08:00
    @damngood 我也是做手游的, 交流一下

    我QQ 330912736
    damngood
        13
    damngood  
       2014-11-21 21:58:20 +08:00
    @yueyoum 多谢抬爱.
    不过我很少上 qq 聊天. 一般最多上下手机 qq. 真有事情才上桌面 qq. 没啥就是觉得 Mac qq 太耗 cpu 了...
    YORYOR
        14
    YORYOR  
    OP
       2014-11-28 18:46:49 +08:00
    @yueyoum 感谢 之前一直是想把生成的代码也丢进去,后来发现多余了 submmodule里面只放pb文件就行!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3223 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 13:36 · PVG 21:36 · LAX 06:36 · JFK 09:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.