google 的protobuf 的序列化效率高,但是也有诸多不便。最大的问题是消息需要预先定义,反序列化需要使用序列化时相同的protobuf 定义。当传输多个格式的消息时,接收端收到一个序列化数据时,并不知道这个消息是什么样的proto 定义。搜索了网络,有大量转发的《Protobuf消息设计原则》中介绍的方式只是将将所以的消息格式,打包成为一个大的消息。我也是这样做的但是总觉得不爽。
突发奇想,为什么不能分层进行序列化呢?
第一层为
Topic 消息主题
Body 消息体
第二层是 消息体
。。。
syntax = "proto3";
package websocket;
message WebsocketMessage {
string Topic =1;
bytes Body=2;
}
message GenericRPC {
string Method =1;
string To=2;
string From =3;
int32 Code=4;
bytes parameters=5;
}
测试程序
package main
import (
"log"
pb "app/WebsocketMessage"
"github.com/golang/protobuf/proto"
"fmt"
)
func main(){
val:=make([]byte,2)
val[0]=0
val[1]=1
genericRPC:=pb.GenericRPC{
Method:"register.app",
From:"gpio",
To:"coreservice",
Code:0,
Parameters:val,
}
data, err := proto.Marshal(&genericRPC)
if err != nil {
log.Fatal("genericRPC marshaling error: ", err)
}
websocketMessage:=pb.WebsocketMessage{
Topic:"weatherstation.RPC",
Body:data,
}
mes, err := proto.Marshal(&websocketMessage)
if err != nil {
log.Fatal("wesocketMessage marshaling error: ", err)
}
deWebsocketMessage := &pb.WebsocketMessage{}
err = proto.Unmarshal(mes, deWebsocketMessage)
if err != nil {
log.Fatal("websocketMessage unmarshaling error: ", err)
}
fmt.Printf("Topic=%s\n",deWebsocketMessage.Topic)
deGenericPRC := &pb.GenericRPC{}
err = proto.Unmarshal(deWebsocketMessage.Body, deGenericPRC)
if err != nil {
log.Fatal("websocketMessage unmarshaling error: ", err)
}
fmt.Printf("Method=%s\n",deGenericPRC.Method)
}
哇,不错呀!