starwing / lua-protobuf

A Lua module to work with Google protobuf
MIT License
1.73k stars 387 forks source link

空数组encode请教 #207

Closed JieTrancender closed 2 years ago

JieTrancender commented 2 years ago

之前使用版本为0.3.3,升级到最新版本以后encode仿佛有了变化。 嵌套结构的空数组仿佛不会有默认值到客户端了。

message XXXCommonInfo {
    repeated uint32 targetedList = 1;  // 新版本客户端解析不出来
}

message XXXInfo {
    optional uint32 err    = 1;
    optional XXXCommonInfo = 2;
}

message GetCommonInfoR {
    optional XXXInfo xxxInfo = 1;
}

请问有optional能保证一样不?测试了pb.option "encode_default_values"依然不行的样子。

JieTrancender commented 2 years ago

回退到了0.3.3版本然后同步了部分提交之后满足了需求。 至于是哪些提交导致了表现不一致晚些时候再追踪一下。

starwing commented 2 years ago

我做了一个重构版本你可以试一下,这个版本设置了pb.option "decode_default_array"就可以在没有编码消息的时候做一个空数组出来了。

JieTrancender commented 2 years ago

我做了一个重构版本你可以试一下,这个版本设置了pb.option "decode_default_array"就可以在没有编码消息的时候做一个空数组出来了。

这个是有意义的。 不过当前可能需要的是一个“encode_default_array”新版本,它会将默认值信息加进去,其他客户端可以解出来。

starwing commented 2 years ago

本来就有个encode_default_values的选项。

但是我要提醒你,这样是不标准的。

JTrancender @.***> 于2022年7月25日周一 22:57写道:

我做了一个重构版本你可以试一下,这个版本设置了pb.option "decode_default_array" 就可以在没有编码消息的时候做一个空数组出来了。

这个是有意义的。 不过当前可能需要的是一个“encode_default_array”新版本,它会将默认值信息加进去,其他客户端可以解出来。

— Reply to this email directly, view it on GitHub https://github.com/starwing/lua-protobuf/issues/207#issuecomment-1194161957, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAA36M2VR2YXC43VSB2YCNTVV2TOTANCNFSM54KRGXEA . You are receiving this because you modified the open/close state.Message ID: @.***>

-- regards, Xavier Wang.

JieTrancender commented 2 years ago

是的,正确做法就是客户端处理,我们大多地方都是这样的,但是因为前面0.3.3掩盖了这个问题导致部分地方没有暴露出来。 项目已经上线没办法快速检测是否所有地方都有正确处理(已经发现了两处),所以暂时想保持原样,稳健点。 前面有看到这个选项的,有设置不能达到理想效果的,最小示例如下:

local pb = require "pb"
local protoc = require "protoc"

assert(protoc:load [[
    message XXXInfo {
        optional uint32 level       = 1;
        repeated uint32 rewardsList = 2;
    }

    message GetXXXInfo {

    }

    message GetXXXInfoR {
        optional uint32 err      = 1;
        optional XXXInfo xxxInfo = 2;
    }
]])

local data = {
    err = 0,
    xxxInfo = {
        level = 0,
        rewardsList = {},
    }
}

local bytes = assert(pb.encode("GetXXXInfoR", data))
print(pb.tohex(bytes))

pb.option "encode_default_values"
local ret = assert(pb.decode("GetXXXInfoR", bytes))
print(require "serpent".block(ret))

执行结果为:

bash-4.1# lua test2.lua
08 00 12 02 08 00
{
  err = 0,
  xxxInfo = {
    level = 0
  } --[[table: 0x1b30b20]]
} --[[table: 0x1b30aa0]]
JieTrancender commented 2 years ago

抱歉,开始没看完最近的修改,刚看到这一条修改同步后就可以了。非常感谢。 https://github.com/starwing/lua-protobuf/blob/6719a107bda7419e63f0ecaf67e69f540b3457aa/pb.c#L1627-L1630

JieTrancender commented 2 years ago

是的,正确做法就是客户端处理,我们大多地方都是这样的,但是因为前面0.3.3掩盖了这个问题导致部分地方没有暴露出来。 项目已经上线没办法快速检测是否所有地方都有正确处理(已经发现了两处),所以暂时想保持原样,稳健点。 前面有看到这个选项的,有设置不能达到理想效果的,最小示例如下:

local pb = require "pb"
local protoc = require "protoc"

assert(protoc:load [[
    message XXXInfo {
        optional uint32 level       = 1;
        repeated uint32 rewardsList = 2;
    }

    message GetXXXInfo {

    }

    message GetXXXInfoR {
        optional uint32 err      = 1;
        optional XXXInfo xxxInfo = 2;
    }
]])

local data = {
    err = 0,
    xxxInfo = {
        level = 0,
        rewardsList = {},
    }
}

local bytes = assert(pb.encode("GetXXXInfoR", data))
print(pb.tohex(bytes))

pb.option "encode_default_values"
local ret = assert(pb.decode("GetXXXInfoR", bytes))
print(require "serpent".block(ret))

执行结果为:

bash-4.1# lua test2.lua
08 00 12 02 08 00
{
  err = 0,
  xxxInfo = {
    level = 0
  } --[[table: 0x1b30b20]]
} --[[table: 0x1b30aa0]]

至于这个,加了pb.option "decode_default_array"之后能正确解析出来。 不过仅仅加pb.option "encode_default_values"不能按预期解析出来。

starwing commented 2 years ago

你的代码有两个问题:

  1. pb2默认不是packed的,repeated有两种模式,packed和非packed,非packed没办法搞默认编码(因为本来就没有“单个数组”这么一个实体),所以你至少需要有一个 packed = true
  2. 你的pb.option好歹需要放encode前面,不然当然不生效了。

两个问题修改后得到了正确的结果:

local pb = require "pb"
local protoc = require "protoc"

assert(protoc:load [[
    message XXXInfo {
        optional uint32 level       = 1;
        repeated uint32 rewardsList = 2 [packed=true];
    }

    message GetXXXInfo {

    }

    message GetXXXInfoR {
        optional uint32 err      = 1;
        optional XXXInfo xxxInfo = 2;
    }
]])

local data = {
    err = 0,
    xxxInfo = {
        level = 0,
        rewardsList = {},
    }
}

pb.option "encode_default_values"
local bytes = assert(pb.encode("GetXXXInfoR", data))
print(pb.tohex(bytes))

local ret = assert(pb.decode("GetXXXInfoR", bytes))
print(require "serpent".block(ret))
-- 执行结果为:
--
-- bash-4.1# lua test2.lua
-- 12 04 08 00 12 00 08 00
-- {
--   err = 0,
--   xxxInfo = {
--     level = 0,
--     rewardsList = {} --[[table: 0000020C3248B6D0]]
--   } --[[table: 0000020C3247B250]]
-- } --[[table: 0000020C3247B850]]
JieTrancender commented 2 years ago
  1. packed和非packed

尴尬,抱歉。

  1. 我是直接从README复制的代码来测试的,漏了syntax = "proto3";https://github.com/starwing/lua-protobuf/blob/6719a107bda7419e63f0ecaf67e69f540b3457aa/README.md?plain=1#L74-L84
  2. 后面发现了放错位置这个问题,漏改评论了,现在确实是正确的。

最后,再次感谢 @starwing 热心帮助。

starwing commented 1 year ago

你的代码有两个问题:

  1. pb2默认不是packed的,repeated有两种模式,packed和非packed,非packed没办法搞默认编码(因为本来就没有“单个数组”这么一个实体),所以你至少需要有一个 packed = true
  2. 你的pb.option好歹需要放encode前面,不然当然不生效了。

两个问题修改后得到了正确的结果:

local pb = require "pb"
local protoc = require "protoc"

assert(protoc:load [[
    message XXXInfo {
        optional uint32 level       = 1;
        repeated uint32 rewardsList = 2 [packed=true];
    }

    message GetXXXInfo {

    }

    message GetXXXInfoR {
        optional uint32 err      = 1;
        optional XXXInfo xxxInfo = 2;
    }
]])

local data = {
    err = 0,
    xxxInfo = {
        level = 0,
        rewardsList = {},
    }
}

pb.option "encode_default_values"
local bytes = assert(pb.encode("GetXXXInfoR", data))
print(pb.tohex(bytes))

local ret = assert(pb.decode("GetXXXInfoR", bytes))
print(require "serpent".block(ret))
-- 执行结果为:
--
-- bash-4.1# lua test2.lua
-- 12 04 08 00 12 00 08 00
-- {
--   err = 0,
--   xxxInfo = {
--     level = 0,
--     rewardsList = {} --[[table: 0000020C3248B6D0]]
--   } --[[table: 0000020C3247B250]]
-- } --[[table: 0000020C3247B850]]

JTrancender @.***> 于2022年7月26日周二 10:33写道:

是的,正确做法就是客户端处理,我们大多地方都是这样的,但是因为前面0.3.3掩盖了这个问题导致部分地方没有暴露出来。 项目已经上线没办法快速检测是否所有地方都有正确处理(已经发现了两处),所以暂时想保持原样,稳健点。 前面有看到这个选项的,有设置不能达到理想效果的,最小示例如下:

local pb = require "pb" local protoc = require "protoc"

assert(protoc:load [[ message XXXInfo { optional uint32 level = 1; repeated uint32 rewardsList = 2; }

message GetXXXInfo {

}

message GetXXXInfoR {
    optional uint32 err      = 1;
    optional XXXInfo xxxInfo = 2;
}

]])

local data = { err = 0, xxxInfo = { level = 0, rewardsList = {}, } }

local bytes = assert(pb.encode("GetXXXInfoR", data)) print(pb.tohex(bytes))

pb.option "encode_default_values" local ret = assert(pb.decode("GetXXXInfoR", bytes)) print(require "serpent".block(ret))

执行结果为:

bash-4.1# lua test2.lua 08 00 12 02 08 00 { err = 0, xxxInfo = { level = 0 } --[[table: 0x1b30b20]] } --[[table: 0x1b30aa0]]

至于这个,加了pb.option "decode_default_array"之后能正确解析出来。 不过仅仅加pb.option "encode_default_values"不能按预期解析出来。

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you modified the open/close state.Message ID: @.***>

-- regards, Xavier Wang.