Skip to content
This repository has been archived by the owner on Nov 28, 2022. It is now read-only.

当proto定义空字段的message时,parser报错 #16

Closed
lsaint opened this issue Aug 9, 2013 · 12 comments
Closed

当proto定义空字段的message时,parser报错 #16

lsaint opened this issue Aug 9, 2013 · 12 comments

Comments

@lsaint
Copy link

lsaint commented Aug 9, 2013

message foo {
}

parser报错

@cloudwu
Copy link
Owner

cloudwu commented Aug 9, 2013

没有字段的 message 是合法的么?

@lsaint
Copy link
Author

lsaint commented Aug 9, 2013

是的,protoc是可以生成空字段的。

@cloudwu
Copy link
Owner

cloudwu commented Aug 9, 2013

我指的是协议上是不是合法的. 而不是 protoc 这个具体实现. 也可能是 protoc 不检查而已.

虽然我觉得不应该有空的 message (定义出来就是 bug), 不过还是把 parser 里检查空 message 的去掉了.

@cloudwu cloudwu closed this as completed Aug 9, 2013
@lsaint
Copy link
Author

lsaint commented Aug 9, 2013

我觉得空的message有存在的必要,在一些小型的项目里面有的协议确实用不上字段,相当于是个开关指令,比如定义一个pause协议,就不需要什么参数。

@cloudwu
Copy link
Owner

cloudwu commented Aug 9, 2013

定义一个空的 message 和不定义这个 message 对 protobuff 来说是一样的. 因为即使你定义了一个没有参数的 pause 协议, 发送这个协议和 protobuff 也没有关系. 就是说,识别你的协议是 pause 还是别的什么, 和 proto buffer 没有关系. 你定不定义 pause 也不是 protobuff 关心的事情.

@cloudwu
Copy link
Owner

cloudwu commented Aug 9, 2013

如果空 message 作为另一个消息的子结构. 那么, 因为 protobuff 有 default 值的定义, 而一个 message 为空就是 default 状态. 按协议是可以不打包的. 具体是否打包可以由实现来决定. 在我的 pbc 的实现中, 如果一个 message 为空, 是永远不会打包的 (在最终的数据流中不存在). 所以定义一个空 message 就失去了意义.

@lsaint
Copy link
Author

lsaint commented Aug 9, 2013

我不太理解,但我想描述一下做为上层使用时的一个场景:
客户端和服务器用protobuff做为相互通讯的唯一通道,在这些message中使用者不心这里头的实现,他想要的效果只是序列化1个message_a,加上uri,加上长度,打包为二进制发送给对端。对端根据长度和uri反序列化出这个message_a而不>是message_b,这个message_a有可能有字段,也有可能没有字段,或者将来可能会加上字段.这种情况总不能让使用者针>对空message做一个特殊处理把?

@cloudwu
Copy link
Owner

cloudwu commented Aug 9, 2013

我的意思是,即使你序列化了 message_a, 只加上长度是不够的, 你必须说清楚这是个 message_a. 可以发字符串也可以发 id, 这些都用 protobuff 之外的协议来约定. 通常你需要有一个自定义协议来描述这个东西. 这份东西里写清楚 message_a 不用 protobuffer 编码就可以了.

@lsaint
Copy link
Author

lsaint commented Aug 9, 2013

上面提到的uri指的就是你说的id吧。看来我们分歧就在与:你认为对空协议该做特殊处理,而我觉得不应该。

@lsaint
Copy link
Author

lsaint commented Aug 12, 2013

假设buf是空协议pause encode后的二进制数据,这个buf可能是空的(google的实现也是),但我觉得使用者不用关心怎么实现,也不用在乎buf是否是空,在乎的是当他用buf来decode协议时,还能decode出pause来,这个在google的实现里面是可以的,希望云风大大的这个pbc也能和google的做法相同.

@cloudwu
Copy link
Owner

cloudwu commented Aug 12, 2013

不是一直都是支持的 ?

parser 那里只是做了个检查, 前几天已经把检查去掉了.
btw, 即使不是空协议, 打包的结果也可能是空的. (如果都是默认值)

@lsaint
Copy link
Author

lsaint commented Aug 12, 2013

噢,刚又试了一下,因为之前都是encode后写入文件,然后读出文件内容再decode的方式,这种在python下没问题,因为python下空文件读出来是""(空字符), 而lua读出来的是nil,所以decode出错了,改""就可以。

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants