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)
}
哇,不錯呀!