protocol-buffers - 您可以为重复的 Protobuf 消息中的一个字段分配多个不同的值类型吗?
问题描述
我正在尝试对将音频文件上传到服务器的客户端进行逆向工程,然后在单独的请求中上传文件的元数据。元数据在 Protobuf 中被序列化,它使用相当简单和可读的结构。这是它之后的样子protoc --decode_raw
:
1 {
1: "title"
2: "This is the audio title"
}
1 {
1: "tags"
2 {
}
}
1 {
1: "loc"
2: "This is the location"
}
1 {
1: "transcription"
2: "A transcript"
}
1 {
1: "mapping"
2 {
1 {
1: 6
2 {
3: 840
}
}
2: 6
}
}
它似乎只是字段的重复消息,1
每次都包含一个键值对,但有时该值是一个字符串,有时它是一个更复杂的消息。2
如果 Protobuf 只允许您在每个字段中使用一种值类型,他们如何将字符串和消息都分配给字段?如果我要制定自己的请求,我需要这样的东西:
message KeyValuePair {
string key = 1;
oneof value {
string str_value = 2;
MessageValue msg_value = 2;
}
}
但这不起作用,因为Field number 2 has already been used in "package.name" by field "str_value"
. 有任何想法吗?我将使用 Python 创建和发送请求数据。
解决方案
有一种官方方法可以实现这一点:google.protobuf.Any
如果 protobuf 模式在顶层定义了 any,例如:
message Root {
repeated google.protobuf.Any value = 1;
}
message Title {
string title= 2;
}
message Tags {
string name = 1;
repeated string tags = 2;
}
然后可以在列表中序列化任何 Protobuf 定义类型的消息。
但是,我不认为这是现有代码正在做的事情:
- 的原始输出
Any
通常包括type.googleapis.com
类型 url - 使用
Any
,title / loc 字段将被封装在嵌套对象中,而不是同一级别的字符串。
例如:
1 {
1: "type.googleapis.com/Title"
2 {
1: "the title"
}
}
推荐阅读
- android - Android,直接从扬声器录制/流式传输
- android - Flutter iOS中的匿名身份验证错误
- java - Keycloak Java Adapter 属性“public-client”是什么意思?
- python - 如何在类定义中定义和使用不会成为 Python 中的类变量的变量
- javascript - 使用视频文件 url 从 azure blob 存储下载视频文件时遇到问题
- javascript - 在 MongoDB 中创建嵌套聚合
- android-jetpack-compose - 使用轮廓 Jetpack Compose 创建芯片
- binding - SwiftUI 更新 NavigationLink(destination:label) 中的 @Binding 值导致目的地重新出现
- javascript - 如何在单击时切换具有相同类名的多个元素
- javascript - WEBGL P5js 未将图像显示为纹理