lua代码格式化工具_在Lua中“优雅”地使用Protobuf

Protobuf有着出色的性能、优秀的版本兼容性并且支持当下大部分的主流语言,在各种网络通信场景中被广泛使用。Lua作为一种效率极高的脚本语言,它可以方便得被嵌入到C程序中,并且支持热更新代码,在游戏行业不管是客户端还是服务器都很受欢迎。所以我想在Lua中使用Protobuf这个需求应该“合情合理”。但是,我在Protobuf中并未发现有Lua的官方版本实现。在一顿百度后发现有几个第三方的实现,不过感觉都不是特别满意。

protoc-gen-lua:https://github.com/sean-lin/protoc-gen-lua

这个库的用法和C++版本的比较接近,通过工具生成每个message的代码,在Lua里面new一个message出来进行赋值,最后通过msg:SerializeToString()将其序列化成二进制。这种使用方式在Lua里面很不方便,没有了脚本语言的优势。

pbc:https://github.com/cloudwu/pbc

云风写的一个C库,自己解析了proto文件并按照protobuf的数据格式来打包解包,接口设计得挺好的,但是看评论有一些bug(好像是反序列化出来的table修改后再序列化会有问题)并且也没再维护了的样子。后面又搞了个他自己的协议sproto,但是这个sproto是不兼容protobuf的,所以使用场景的局限性太大。

lua-protobuf:https://github.com/starwing/lua-protobuf

这个库是相对比较满意的一个实现,代码轻量、接口和pbc类似,自己解析proto协议文件,传一个Lua的table可以直接encode成二进制数据,decode二进制数据可以直接生成一个table。因为整个库都是完全脱离Protobuf的代码自己手写的,没有完整得去读过它的代码,所以也不作太多的评价,因为我个人比较信任官方库和自己。

因为在序列化submessage的时候需要填一个“变长”编码的长度信息,自己实现的库这个会是非常的棘手。要么先算一次submessage的长度(在Lua中效率低),要么是需要将数据“分片”最后再将它们拷贝到一块连续的内存空间,要么是用定长的方式来兼容变长的编码方式。但是感觉这3种方式都不太满意,我猜这个库应该是使用的第二种方式

我不太想对它作太深入的了解,因为我觉得就用Protobuf的标准库,通过它的反射接口来实现和Lua的对接实现起来应该很简单,并且这样实现出来的Bug应该会是比较可控,也可以快速得支持Protobuf的新增特性(如支持Map等),所以我参照着前人的接口使用Protobuf原生的C++库实现了按照自己的想法实现了一个Lua的库,实际代码应该不到1000行。

我的protolua:https://github.com/jinjiazhang/protolua

syntax 
require 

用法也比较类似,同时支持proto2和proto3,导出了几个Lua的接口,parse、encode、decode、pack、unpack。或者直接在网络收发包那里直接调用C函数来pack、unpack可以少一次内存拷贝。我写的代码主要也就是通过协议名字找到对应的协议描述Descriptor*,然后遍历它的fields,通过字段名从Lua的table中取值然后在用Protobuf的反射接口给Message赋值,最后再调用message->SerializeToString()来序列化,反序列化的代码刚好相反。

实际应用中是长这个样子的:

message 
function 

新加一条协议服务器只需要找个地方实现一个net.csxxx_req() 函数,并且通过ss.cs_xxx_rsp()来给客户端回包,参数顺序都是按协议的字段num顺序一一对应的。消息注册、派发这些代码都不需要,只需要专注于业务逻辑的实现,可以大大提高开发效率。按照同样的封装思路也可以将角色数据根据proto的描述信息将它写入到mysql、mongodb、redis中,这样整个服务器的数据和逻辑就都在Lua里了,热跟新修复Bug、不停机维护都可以在这个的基础上轻易实现。

如果有任何为题可以直接给我发私信,写这篇文章的目的一是为了稍微“推广”一下,二是想了解不同人的需求,使之更完善,三是结识更多同行业人士。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值