Go语言中解码带自定义类型头部的Protobuf消息的符合语言习惯的实现方案咨询
Go语言中解码带自定义类型头部的Protobuf消息的符合语言习惯的实现方案咨询
我正在尝试为我们内部的Protobuf框架实现一个Go语言的扩展。我们已经在C、Python和其他几种语言的多个服务中实现了这个框架,所以修改消息格式是不可能的。我想找到最符合Go语言习惯(同时最省心)的实现方式。
我们的做法是给所有Protobuf消息前面加上一个小头部,其中一个字段表示消息类型。在这个框架里编码消息其实很简单:
const ( MessageEmpty = iota Message1 Message2 ) func Encode(msgType byte, msg proto.Message) ([]byte, error) { buf, err := proto.Marshal(msg) if err != nil { return nil, err } hdr := Header { msgtype: msgType, } out := new(bytes.Buffer) err = binary.Write(out, binary.BigEndian, hdr) if err != nil { return nil, err } out.Grow(len(buf)) _, err = out.Write(buf) if err != nil { return nil, err } return out.Bytes(), nil }
我还没彻底测试这段代码,但初看起来是对的。不过我现在遇到的问题是编写Decode()函数。我想实现的逻辑大概是这样的:
func Decode(pkt []byte) (proto.Message, error) { hdr := Header{} buf := bytes.NewBuffer(pkt) ret := proto.Message() err := binary.Read(buf, binary.BigEndian, &hdr) if err != nil { return nil, err } msg := buf.Bytes() switch hdr.msgType { case Message1: pbmsg := myproto.FirstMessage{} err = proto.Unmarshal(msg, &pbmsg) ret = &pbmsg case Message2: } if err != nil { return nil, err } return ret, nil }
但这段代码编译不通过。而且接下来我还会遇到一个问题:当我得到消息后,如何在运行时判断它的类型?(我想过可以把msgType字段也作为返回值之一)
欢迎任何建议和指导。
备注:内容来源于stack exchange,提问作者Ken P
相关产品推荐
相关产品推荐

