暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

「Golang」关于通过proto消息名,创建proto.Message对象

Echo的技术笔记 2021-03-02
2450

  之前在做一些proto相关业务逻辑编写,在编写过程中,需要通过proto的message full name 去动态的创建一个proto.Message对象,在网上找一些相关的内容也没找到,所以就自己研究了一下并且实现了这个功能。

下面是proto v1版本实现代码。

//该实现仅用于proto v1版本实现 即    github.com/golang/protobuf 库
func parseRequest(msgName protoreflect.FullName, data []byte) (proto.Message,error) {
// 获取full name对应的message ,如果不存在则返回error
msgType, err := protoregistry.GlobalTypes.FindMessageByName(msgName)
if err != nil {
return nil, err
}
//上面返回的是一个message 反射类型,需要把它new出一个 protoreflect.Message类型然后转换成protoiface.MessageV1
//此时 根据源代码显示 proto.Message实现为 type Message = protoiface.MessageV1
//即type Message 为 protoiface.MessageV1 的别名
msg := proto.MessageV1(msgType.New())
err = proto.Unmarshal(data, msg)
if err != nil {
return nil, err
}
return msg, nil
}

复制

proto v2版本实现如下

//该实现仅用于proto v2版本实现 即"google.golang.org/protobuf/proto"
func parseRequest(msgName protoreflect.FullName, data []byte) (proto.Message,error) {
// 获取full name对应的message ,如果不存在则返回error
msgType, err := protoregistry.GlobalTypes.FindMessageByName(msgName)
if err != nil {
return nil, err
}
//上面返回的是一个message type 反射类型,需要把它new出一个 protoreflect.Message类型然后转换成protoreflect.ProtoMessage
//此时 根据源代码显示 proto.Message实现为 type Message = protoreflect.ProtoMessage
//即type Message 为 protoreflect.ProtoMessage的别名
msg := msgType.New().Interface()
err = proto.Unmarshal(data, msg)
if err != nil {
return nil, err
}
return msg, nil
}

复制

  整体业务流程是,传进一个proto的 full name 然后根据这个名字去创建对应的message,然后把data 解析到这个message中。

关于protov1 v2版本的区别,v2版本的动态特性更强。具体区别请看下面的链接 https://www.infoq.cn/article/dyX9bq5uFyK4hCEPgmuj[1]

References

[1]
 https://www.infoq.cn/article/dyX9bq5uFyK4hCEPgmuj: https://www.infoq.cn/article/dyX9bq5uFyK4hCEPgmuj


文章转载自Echo的技术笔记,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论