golang 根据protobuf消息名称获取实例对象

今天在使用golang的protoful作为通信消息协议的时候,发现我们必须手动写死消息名称来对应处理消息的func,极为不便,不符合策略模式的设计模式,经过一天的查找最终找到以下解决方法

获取proto Message的全类名

// GetFullNameByMessage 获取pb协议的全类名
func GetFullNameByMessage(msg proto.Message) string {
   reflect := proto.MessageReflect(msg)
   descriptor := reflect.Descriptor()
   name := descriptor.FullName()
   return string(name)
}

根据proto全类名获取Message实例

func GetMessageByFullName(fullName string, data []byte) proto.Message {
	msgName := protoreflect.FullName(fullName)
	msgType, err := protoregistry.GlobalTypes.FindMessageByName(msgName)
	if err != nil {
		logger.Errorf("FindMessageByName err: %v", err)
		return nil
	}
	msg := proto.MessageV1(msgType.New())
	err = proto.Unmarshal(data, msg)
	if err != nil {
		logger.Errorf("proto Unmarshal err: %v", err)
		return nil
	}
	return msg
}

该方法只在golang proto v1版本才能使用,也就是github.com/golang/protobuf的包名

如果是V2版本请使用以下方法,也就是google.golang.org/protobuf/proto

// GetMessageV2ByFullName 根据pb全类名获取消息实例
func GetMessageV2ByFullName(fullName string, data []byte) proto.Message {
	msgName := protoreflect.FullName(fullName)
	msgType, err := protoregistry.GlobalTypes.FindMessageByName(msgName)
	if err != nil {
		logger.Errorf("FindMessageByName err: %v", err)
		return nil
	}
	message := msgType.New().Interface()
	err := proto.Unmarshal(data, message)
	if err != nil {
		return nil
	}
	return message
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值