protobuf_app.lua 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. --[[
  2. @module protobuf_app
  3. @summary protobuf 编解码功能模块
  4. @version 1.0
  5. @date 2025.10.31
  6. @author 马梦阳
  7. @usage
  8. 本功能模块演示的内容为:
  9. 1.加载 protobuf 定义文件;
  10. 2.将符合 protobuf 定义的 Lua table 数据编码为二进制数据;
  11. 3.使用 json 编码同样的 Lua table 数据后,对比 protobuf 和 json 编码后数据的大小;
  12. 4.将二进制数据解码为 Lua table 数据;
  13. 5.清除所有已加载的定义数据;
  14. 本文件没有对外接口,直接在 main.lua 中 require "protobuf_app" 就可以加载运行;
  15. ]]
  16. local function main_task()
  17. -- 加载 pb 文件, 这个是 proto 经过 protoc.exe 编译后生成的二进制文件
  18. -- 下载资源到模块时不需要下载 proto 文件
  19. -- 转换命令: protoc -o person.pb person.proto
  20. -- protoc.exe 下载地址: https://github.com/protocolbuffers/protobuf/releases
  21. local pb_file = "/luadb/person.pb"
  22. local tbdata = {
  23. name = "wendal",
  24. id = 123,
  25. email = "abc@qq.com"
  26. }
  27. if io.exists(pb_file) then
  28. local success, bytesRead = protobuf.load(io.readFile(pb_file))
  29. if not success then
  30. log.info("protobuf", "加载 protobuf 定义失败,已读取 " .. bytesRead .. " 字节")
  31. return
  32. else
  33. log.info("protobuf", "加载 protobuf 定义成功,共解析 " .. bytesRead .. " 字节")
  34. end
  35. else
  36. log.info("protobuf", "pb 文件不存在")
  37. return
  38. end
  39. -- 编码数据;
  40. local pbdata = protobuf.encode("Person", tbdata)
  41. if pbdata then
  42. -- 编码成功,编码后的数据通常包含不可见字符;
  43. -- 打印长度和十六进制内容(便于调试);
  44. log.info("protobuf", "编码成功,数据长度:" .. #pbdata)
  45. log.info("protobuf", "十六进制内容:" .. pbdata:toHex())
  46. else
  47. log.info("protobuf", "编码失败:数据格式或类型不匹配")
  48. end
  49. -- 对比 protobuf 编码和 json 编码的大小;
  50. local jdata = json.encode(tbdata)
  51. if jdata then
  52. log.info("json", "编码成功,数据长度:" .. #jdata)
  53. log.info("json", "数据内容:" .. jdata)
  54. else
  55. log.info("json", "编码失败:数据格式或类型不匹配")
  56. end
  57. -- 可见 protobuffs 比 json 节省很多空间;
  58. -- 数据解码;
  59. local tbdata = protobuf.decode("Person", pbdata)
  60. if tbdata then
  61. -- 解码后的数据为 Lua table 格式,需要转化为 json 进行显示;
  62. log.info("protobuf", "解码成功,数据内容:", json.encode(tbdata))
  63. else
  64. log.info("protobuf", "解码失败")
  65. end
  66. -- 清除所有已加载的定义数据;
  67. protobuf.clear()
  68. log.info("protobuf", "所有 protobuf 定义已清除")
  69. end
  70. -- 创建并启动一个 task
  71. -- 用于运行 main_task 函数
  72. sys.taskInit(main_task)