根据消息名称解析protobuf格式

2019-10-30  本文已影响0人  fzhyzamt

最近在解析一个网站的websocket时,发现使用的是protobuf,每个消息都使用一个统一的Wrapper封装,wrapper中包含有这条消息的pb名字以及对应的实际数据,这样就可以同时在同步通讯和通知中解析不同类型的消息了。

# 原格式
"Wrapper": {
    "fields": {
        "data": {
            "id": 2,
            "type": "bytes"
        },
        "name": {
            "id": 1,
            "type": "string"
        }
    }
}
# 转换为.proto
type Wrapper struct {
    Name                 string   `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
    Data                 []byte   `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
    XXX_NoUnkeyedLiteral struct{} `json:"-"`
    XXX_unrecognized     []byte   `json:"-"`
    XXX_sizecache        int32    `json:"-"`
}
未解码的Message
其中.lq.RecordDealTile为pb中的消息名称,那么只需要对每个消息根据名称实例化对应的消息就可以了。
golang中语言级别是没有遍历包下所有类型的方法的,不过好在protobuf解决了这个问题,在生成的.pb.go中我们可以看到,每个类型都被注册到了proto中,我们需要使用的时候直接去获取就可以了。
liqi.pb.go
首先进行解码
func unWrap(b []byte) (s string, data []byte, err error) {
    wrapper := lq.Wrapper{}
    if err := wrapper.XXX_Unmarshal(b); err != nil {
        fmt.Println("UnWrapper fail", err)
        return "", nil, err
    }
    return wrapper.Name, wrapper.Data, nil
}

在解析数据时,直接使用proto.MessageType(name)即可获得对应的消息类型。

fmt.Println(proto.MessageType(name))
> *lq.RecordDiscardTile
上一篇 下一篇

猜你喜欢

热点阅读