你好,我是 gRPC 和 ProtoBuf 的新手 我正在尝试通过 grpc 从用 Go 编写的微服务进行通信。 在某些操作中,要发送请求,我需要设置在发送请求时键入消息。我阅读了一些 golang 和 python 语言的资料。这就是他们确定消息类型的方式。
我在打字稿中有一个带有 TypedMessage 名称的命名空间,用于保存消息类型和消息值:
export namespace TypedMessage {
export type AsObject = {
type: string,
value: Uint8Array | string,
}
}
我需要将每条消息转换为这种类型,所以我写了这样一个函数:
function toTypedMessage(message: proto.Message) {
const typedMessage = new TypedMessage();
typedMessage.setType("Its not complete");
typedMessage.setValue(message.serializeBinary());
return typedMessage;
}
我的灵感来自于 Python 和 Go 资源:
去:
func GetMessageType(message proto.Message) string {
return string(message.ProtoReflect().Descriptor().FullName())
}
func ToTypedMessage(message proto.Message) *TypedMessage {
if message == nil {
return nil
}
settings, _ := proto.Marshal(message)
return &TypedMessage{
Type: GetMessageType(message),
Value: settings,
}
}
Python:
class Message:
def __new__(cls, message) -> TypedMessage:
return TypedMessage(
type=message.DESCRIPTOR.full_name,
value=message.SerializeToString()
)
我这部分的问题是我写的函数
typedMessage.setType("");
众所周知,这个值必须是一个字符串。根据 Go 和 Python 来源,需要一个描述符来将消息返回到原型名称,例如 go 中的 message.ProtoReflect().Descriptor().FullName()
和 python 中的 message.DESCRIPTOR.full_name
。但nodeJS google-protobuf中似乎没有这样的东西。
还有没有其他解决办法?
我看到了不同的来源。但我无法解决问题 这里也有人说过这样的话:
不幸的是,这不受支持。
其他语言在生成的代码中嵌入了 proto 文件的“描述符”。描述符包含有关消息、其字段以及自定义选项的信息,全部采用二进制 protobuf 格式。参见描述符.proto
生成读取扩展的代码。如果您有 FieldDescriptor,您可以读取您的 FieldOption 扩展。但是 Javascript 生成的代码中没有这个描述符。
有一个可能的解决方法:您可以使用 protoc 为 .proto 文件转储 FileDescriptorSet(请参阅 --descriptor_set_out 选项)。您可以使用 Javascript(来自 google-protobuf 的 proto.google.protobuf.FileDescriptorSet)读取此二进制消息,导航到您的消息、相关字段,然后读取您的扩展数据以获取自定义选项值。
出于代码大小和信息泄露的原因,用于 javascript/typescript 的 google-protobuf 不支持反射。