Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

protobuf中带有二进制数组使用rpc会改变二进制数组cap #141

Open
huangbwww opened this issue Aug 9, 2023 · 4 comments
Open

Comments

@huangbwww
Copy link

如题,使用这套rpc进行通信是,请求参数使用protobuf,如果含有protobuf的bytes类型,可能导致rpc_server接收到的二进制数组cap发生改变,进而导致解析报错。

@liangdas
Copy link
Owner

liangdas commented Aug 9, 2023

我最近也用到了protobuf的bytes类型,貌似么有发现问题,是必现吗?是否有示例参考一下

@huangbwww
Copy link
Author

huangbwww commented Aug 10, 2023

嗯 我把我大概使用场景贴给你看看
我的proto

message UpdatePlayerDataReq {
  uint64 account_id = 1;
  string nickname = 2;
  bytes data = 3;
}

rpc调用方

err = mqrpc.Proto(rsp, func() (reply interface{}, err interface{}) {
	return proxy.cli.Call(context.TODO(), “db_proxy”, "updateplayerdata", mqrpc.Param(req))
})

rpc接收方
注册
m.GetServer().RegisterGO("updateplayerdata", ser.UpdatePlayerData)

UpdatePlayerData接口

func (dm *DBProxyModule) UpdatePlayerData(req *pb.UpdatePlayerDataReq) (*pb.Empty, error) {
	return &pb.Empty{}, nil
}

这是我第一个使用bytes在rpc间进行传输的协议,一开始我的data数据是一个protobuf的二进制又经过了snappy压缩,出现的问题是发送时的请求参数encode的protobuf二进制的cap要比接收方收到的大,二进制数据时对的,所以proto解码req这个请求参数时报了一个无效二进制的报错。

然后我就尝试去掉了data的snppy过程,直接把一个数据通过protobuf进行encode然后放进了data进行传输,这次通讯时完成了但是接收方的req里的数据都是nil,表现像是拿一个nil进行了decode

然后我把二进制搞了下base64字符串,再尝试就没有出现问题。

时间问题我当时尝试成功就先用base64进行传输了,二进制的问题断点看了一点,只看到了第一次的cap问题,等有时间我再尝试看看

@huangbwww
Copy link
Author

huangbwww commented Aug 11, 2023

我又排查了一下,上面说的我漏掉了中间的string,编辑补充上了
同样是这个proto

message UpdatePlayerDataReq {
  uint64 account_id = 1;
  string nickname = 2;
  bytes data = 3;
}

接收方都是用proto
发送方使用ArgType: ProtocolMarshal会有这个问题
如果proto中是uint64+string+bytes的组合,bytes如果是snappy压缩的那就会报错,如果不压缩会解析不出数据,但是我如果去掉中间的string,只发一个uint64+bytes,就都可以用了,对比了bytes内容发现除了cap都一模一样,但是在别的场景下测试发现cap的差别其实不会影响decode

发送方使用ArgType: []byte不会有个问题

具体问题还是没有排查到

@huangbwww
Copy link
Author

huangbwww commented Aug 12, 2023

我知道为啥了,和我的名字叫data有关系,ProtocolMarshal接口内的func叫做GetData(),这样我生成的proto的data字段会带有GetData(),这个结构就会被识别为ProtocolMarshal,然后底层2Bytes或者2Args的时候会判定进ProtocolMarshal,通过接口的GetData来获取二进制,这样就把二进制给损坏了。
应该就是这个原因,前面没有再仔细地进更里面的接口去看原因,今天有时间就往更深调试了下流程,熟悉了下底层流程后就比较快调试到问题所在。大佬可以看看能不能加个注释提醒一下,不要不小心实现了ProtocolMarshal接口,踩到小坑-……

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

No branches or pull requests

2 participants