本文主要涉及从老版本"github.com/golang/protobuf" 迁移为新版本 "google.golang.org/protobuf" 所要注意到的技术细节;其中还有少量新版本使用方法;
1. 获取google代码protobuf
1 2 3 4 5 6 7 8 |
# 配置go 代理 go env -w GOPROXY="https://goproxy.cn,direct" # 下载protobuf代码到${GOPATH}/pkg/google.golang.org/protobuf go get google.golang.org/protobuf # 下载protobuf指定版本 go get google.golang.org/protobuf@v1.27.1 git clone https://ghproxy.com/https://google.golang.org/protobuf |
2. 根据名称获取pb并创建结构体
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
//"github.com/golang/protobuf/jsonpb" //老版本 //"github.com/golang/protobuf/proto" //老版本 "google.golang.org/protobuf/encoding/prototext" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoregistry" // ProtoWithName is used to marshall proto message data alongside the proto // message name. type ProtoWithName struct { ProtoMsgName string ProtoMsgData string } // proto.MarshalTextString(item) 老版本 "github.com/golang/protobuf/proto" // prototext.Marshal(item) 新版本 "google.golang.org/protobuf/encoding/prototext" // MarshalJSON marshalls proto message using the marshaller from jsonpb. // The jsonpb package produces a different output than the standard "encoding/json" // package, which does not operate correctly on protocol buffers. func (p *RecordedProtoMessage) MarshalJSON() ([]byte, error) { var ( msgName string msgData string err error ) if p != nil { msgName = string(proto.MessageName(p.Message)) msgbin, err := proto.Marshal(p.Message) if err != nil { return nil, err } msgData = string(msgbin) } pwn, err := json.Marshal(ProtoWithName{ ProtoMsgName: msgName, ProtoMsgData: msgData, }) if err != nil { return nil, err } return pwn, nil } // UnmarshalJSON un-marshalls proto message using the marshaller from jsonpb. // The jsonpb package produces a different output than the standard "encoding/json" // package, which does not operate correctly on protocol buffers. func (p *RecordedProtoMessage) UnmarshalJSON(data []byte) error { var pwn ProtoWithName if err := json.Unmarshal(data, &pwn); err != nil { return err } p.ProtoMsgName = pwn.ProtoMsgName if p.ProtoMsgName == "" { return nil } //msgType := proto.MessageType(pwn.ProtoMsgName) //老版本 // 获取full name对应的message ,如果不存在则返回error msgType, err1 := protoregistry.GlobalTypes.FindMessageByName(protoreflect.FullName(pwn.ProtoMsgName)) if err1 != nil { return err1 } if msgType == nil { return fmt.Errorf("unknown proto message: %s", p.ProtoMsgName) } //msg := reflect.New(msgType.Elem()).Interface().(proto.Message) //老版本 msg := msgType.New().Interface() var err error if len(pwn.ProtoMsgData) > 0 && pwn.ProtoMsgData[0] == '{' { //err = jsonpb.UnmarshalString(pwn.ProtoMsgData, msg) //老版本 err = proto.Unmarshal([]byte(pwn.ProtoMsgData), msg) //protojson } else { //err = proto.UnmarshalText(pwn.ProtoMsgData, msg) //老版本 err = prototext.Unmarshal([]byte(pwn.ProtoMsgData), msg) } if err != nil { return err } p.Message = msg return nil } |
3. AnyPb 转换 proto.Message
3.1. Marshal Any
1 2 3 4 5 6 7 8 9 10 |
// 老版本 // types "github.com/golang/protobuf/ptypes" // any, err := types.MarshalAny(pb) // 新版本 // "google.golang.org/protobuf/types/known/anypb" any, err := anypb.New(pb) if err != nil { return nil, err } |
3.2. Unmarshal Any
1 2 3 4 5 6 7 8 9 10 11 12 |
// 老版本 // types "github.com/golang/protobuf/ptypes" // var any types.DynamicAny // if err := types.UnmarshalAny(item.GetData().GetAny(), &any); err != nil { // return nil, err // } // 新版本 // "google.golang.org/protobuf/types/known/anypb" if dst,err :=anypb.UnmarshalNew(item.GetData().GetAny(),nil);err != nil { return nil, err } |
3.3. 空proto.Message赋值
1 2 3 4 |
"github.com/golang/protobuf/ptypes/empty" "google.golang.org/protobuf/proto" var Value proto.Message = &empty.Empty{} |
微信赞赏
支付宝赞赏