在網絡傳輸的過程中 數據會比較多 處理起來會比較麻煩,因此得引入分層的概念,
計算機科學領域的任何問題都可以通過增加一個間接的中間層來解決
“Any problem in computer science can be solved by anther layer of indirection.”
在客服端 和 服務器可以制訂一套通信協議, 通信協議是客服端和服務端 共同約定的一個 數據結構,其包含了雙方可以發送,並對方可以識別處理的數據包。
Protobuffer 可以把 一個類的實例序列化,和反序列化, 通過反射機制去取得, 開源的。
也支持JsonMap
github源碼
2019最新版是 3.7,需要.Net 4.5以上
API
protocolbuffer(以下簡稱PB)是google 的一種數據交換的格式,它獨立於語言,獨立於平臺。google
提供了多種語言的實現:java、c#、c++、go 和
python,每一種實現都包含了相應語言的編譯器以及庫文件。由於它是一種二進制的格式,比使用 xml
進行數據交換快許多。可以把它用於分佈式應用之間的數據通信或者異構環境下的數據交換。作爲一種效率和兼容性都很優秀的二進制數據傳輸格式,可以用於諸如網絡傳輸、配置文件、數據存儲等諸多領域。
對一個數據類進行 序列化
項目要添加Pb的引用纔可以
using ProtoBuf;
using ProtoBuf.Meta;
[ProtoContract]
class NetMode
{
[ProtoMember(1)]
public int id;
[ProtoMember(2)]
public string name;
//如果要使用構造函數,那麼 默認構造函數 必須得存在,這個是一個小坑不然會報錯
public NetMode()
{
}
public NetMode(int id,string name)
{
this.id = id;
this.name = name;
}
}
如果 數據類不使用構造函數 則不會報錯
Untiy中其實也有序列化特性
不過 Pb 還加了反射技術,因此客服端服務器 兩邊的數據結構 其實是通用的,不然也用不了Pb,
[ProtoContract]特性 約定特性,可以用於 類 結構體,枚舉,接口
序列化對象
/// <summary>
/// 通過Protobuffer 序列化對象 返回byte[]數組
/// </summary>
/// <param name="value"></param>
/// <returns>二進制數據</returns>
public static byte[] PBSerialize(object value)
{
byte[] data = null;
//在範圍結束時 處理對象
using (MemoryStream ms=new MemoryStream())
{
if (value!=null)
{
// 序列化 到內存裏
Serializer.Serialize(ms, value); //此方法 會調用到以下方法. 實際上是同個方法,多層封裝
RuntimeTypeModel.Default.Serialize(ms, value);
}
//設置當前 位置
ms.Position = 0;
//寫入 數組
long length = ms.Length;
data = new byte[length];
//從內存流中讀取 寫入到buffer中
ms.Read(data, 0, (int)length);
}
return data;
}
public static byte[] Serialize(object obj)
{
using (var memory = new MemoryStream())
{
Serializer.Serialize(memory, obj);
return memory.ToArray();
}
}
反序列化方法
public static T Deserialize<T>(byte[] data)
{
using (var memory = new MemoryStream(data))
return Serializer.Deserialize<T>(memory);
}
public static T Deserialize<T>(byte[] data, int offset, int size)
{
using (var memory = new MemoryStream(data, offset, size))
return Serializer.Deserialize<T>(memory);
}
public static object PBDSerialize( byte[] value ,Type type)
{
object o = null;
using (var memory=new MemoryStream(value))
{
o= RuntimeTypeModel.Default.Deserialize(memory,null, type);
}
return o;
}