Erlang使用ProtoBuffer

最近有工作需要打算为项目服务器做一个机器人,测试测试压力,根据自己的经验,使用Erlang来做是最合适不过的了,但是服务器使用的C++语言,使用了Google的ProtoBuffer作为协议进行数据交换,而Erlang并没有官方的Protobuffer版本支持,官方仅支持C++,JAVA,Python等几种比较主流的语言。在网上搜索了一下,ProtoBuffer的第三方Erlang版本主要有以下几个:

  1. https://github.com/ngerakines/erlang_protobuffs/tree/master
  2. https://github.com/basho/erlang_protobuffs
  3. http://piqi.org/
  4. https://github.com/tomas-abrahamsson/gpb

我使用了一下其中的一两个版本,但是发现有的对import的支持很有限,甚至不支持,而项目中的PB是有用到,最后选定第四个版本gpb,这个版本可以使用项目中的大部分proto文件生成Erlang源文件,仅有import引用的类型有引用前缀的时候不支持。举个例子:

假如现在有两个proto文件,A.proto和B.proto,A.proto中定义了一个枚举:

package A;

enum Type { T_A = 0; T_B = 1; }

 B.proto中引用了这个枚举:

message M_Test
{
    required A.T_A eType = 1;
    optional int32  other = 2;
}

 这个时候编译proto文件,会出现如下错误:

in msg M_Test, field eType: undefined reference  A.T_A

但是如果将B.proto中的消息定义改为:

message M_Test
{
    required T_A eType = 1;
    optional int32  other = 2;
}

则能够成功编译通过。

为了解决这个问题,研究了一下gpb的源码,在gpb_parse.erl中有一个函数:

%% -> {found, {msg,FullName}|{enum,FullName}} | not_found
resolve_ref(Defs, Ref, Root, FullName) ->
    case is_absolute_ref(Ref) of
        true  ->
            FullRef = ensure_path_prepended(Root, Ref),
            find_typename(FullRef, Defs);
        false ->
            PossibleRoots = compute_roots(FullName),
            find_ref_rootwards(PossibleRoots, Ref, Defs)
    end.

这个函数是专门用来解析引用的,其中的变量Ref在第一种写法,其值为:['A','.','T_A'],这个时候解析不了;而第二种方式的写法其值为:['T_A']

如果匹配一下第一种写法的值,然后将之改为第二种写法的值,即可正常编译。为此我加了一个过滤函数如下:

filterRef([_,'.',Type]) -> [Type];
filterRef(Other) -> Other.

 然后把resolve_ref函数改为:

%% -> {found, {msg,FullName}|{enum,FullName}} | not_found
resolve_ref(Defs, Ref0, Root, FullName) ->
    Ref = filterRef(Ref0),
    case is_absolute_ref(Ref) of
        true  ->
            FullRef = ensure_path_prepended(Root, Ref),
            find_typename(FullRef, Defs);
        false ->
            PossibleRoots = compute_roots(FullName),
            find_ref_rootwards(PossibleRoots, Ref, Defs)
    end.

这样,就可以正常的编译项目中所有的Proto文件了。

btw,按gpb官方的介绍来看,其支持proto2以及proto3的语法,但不知道是否完全支持,有待验证。

转载于:https://www.cnblogs.com/witton/p/6858117.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值