unity探索者之socket傳輸protobuf位元組流(一)

来源:http://www.cnblogs.com/unityExplorer/archive/2017/06/10/6974229.html
-Advertisement-
Play Games

版權聲明:本文為原創文章,轉載請聲明http://www.cnblogs.com/unityExplorer/p/6974229.html 近期在做一個棋牌項目,需要用到socket傳輸protobuf位元組流,在網上找了一些博客和文章後發現,沒有特別全面的,所以把自己研究的全部源碼拿出來和大家分享, ...


版權聲明:本文為原創文章,轉載請聲明http://www.cnblogs.com/unityExplorer/p/6974229.html 

近期在做一個棋牌項目,需要用到socket傳輸protobuf位元組流,在網上找了一些博客和文章後發現,沒有特別全面的,所以把自己研究的全部源碼拿出來和大家分享,因為剛開始做,可能會有不足的地方,歡迎拍磚~~

這一篇主要是protocol buffer文件的序列化和解析,廢話不多說了,直接上乾貨

 1 /// <summary>
 2 /// 將消息序列化為二進位的方法
 3 /// </summary>
 4 /// <param name="model">要序列化的對象</param>
 5 public static byte[] Serialize(IExtensible model)
 6 {
 7   try
 8   {
 9     //創建流對象
10     MemoryStream ms = new MemoryStream()
11     //使用ProtoBuf自帶的序列化工具序列化IExtensible對象
12     Serializer.Serialize<IExtensible>(ms, model);
13     //創建二級制數組,保存序列化後的流
14     byte[] bytes = new byte[ms.Length];
15     //將流的位置設為0
16     ms.Position = 0;
17     //將流中的內容讀取到二進位數組中
18     ms.Read(bytes, 0, bytes.Length);
19     return bytes;
20   }
21   catch (Exception e)
22   {
23     Debug.Log("序列化失敗: " + e.ToString());
24     return null;
25   }
26 }

protobuf文件中的每一條message經過protocol buffer提供的ProtoGen工具可以轉成c#的中的類,例如

message Test {
    required string test1= 1;
    required string test2= 2;
}

經過轉化後就變成了

 1   [global::System.Serializable, global::ProtoBuf.ProtoContract(Name=@"SedReq")]
 2   public partial class Test : global::ProtoBuf.IExtensible
 3   {
 4     public Test() {}
 5     
 6     private string _test1;
 7     [global::ProtoBuf.ProtoMember(1, IsRequired = true, Name=@"test1", DataFormat = global::ProtoBuf.DataFormat.Default)]
 8     public string test1
 9     {
10       get { return _test1; }
11       set { _test1 = value; }
12     }    
13     private string _test2;
14     [global::ProtoBuf.ProtoMember(2, IsRequired = true, Name=@"test2", DataFormat = global::ProtoBuf.DataFormat.Default)]
15     public string test2
16     {
17       get { return _test2; }
18       set { _test2 = value; }
19     }
20     private global::ProtoBuf.IExtension extensionObject;
21     global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
22       { return global::ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing); }
23   }

無視所有帶global的代碼,你會發現,轉化後的c#類和一個標準的c#實體類一模一樣,並且,這些轉化後的類都繼承至ProtoBuf.IExtensible,所以上文中的序列化函數的參數的類型是IExtensible

有了序列化,當然還需要反序列化,也就是講byte[]反序列化為繼承至IExtensible的類型的對象

 1     /// <summary>
 2     /// 將收到的消息反序列化成IExtensible對象
 3     /// </summary>
 4     /// <param name="msg">收到的消息的位元組流.</param>
 5     /// <returns></returns>
 6     public static T DeSerialize<T>(byte[] bytes) where T : IExtensible
 7     {
 8         try
 9         {
10             MemoryStream ms = new MemoryStream()
11             //將消息寫入流中
12             ms.Write(bytes, 0, bytes.Length);
13             //將流的位置歸0
14             ms.Position = 0;
15             //反序列化對象
16             T result = Serializer.Deserialize<T>(ms);
17             return result;
18         }
19         catch (Exception e)
20         {
21             Debug.Log("反序列化失敗: " + e.ToString());
22             return null;
23         }
24     }

因為反序列化後的對象是繼承至IExtensible的類的對象,所以返回值必須使用泛型約束來定義,這樣才能保證函數的通用性

工具搞定,接下來就是測試代碼了

1     public void Test()
2     {
3         Test test = new Test() { test1 = "123", test2 = "456" };
4         byte[] bytes = Serialize(test);
5         Test test2 = DeSerialize<Test>(bytes);
6         Debug.Log(test2.test1 + test2.test2);
7     }

輸出結果  123456

附上protobuf-net.dll文件

http://files.cnblogs.com/files/unityExplorer/protobuf-net.zip

預編譯和轉化工具

http://files.cnblogs.com/files/unityExplorer/protoGen.zip


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 看過的相當不錯的一篇文章,但是對基架還時不太理解,大神們看到,希望指點一二,能告訴點學習資源就更好了! 本篇文章不是出自本人之手,轉載完全處於膜拜以及學習! 歡迎加我微信:jkxx123321 備註博客加就可以了! 最近由於需要在框架中提供一些自定義模板的功能,找到了一篇博客,可惜似乎是翻譯工具直接 ...
  • 一、前言 在日常的界面開發中,我們大多使用MVVM模式進行開發。通常情況下,一個PropertyGridControl或者DataGrid的ItemsSource設置好, 然後每一列綁定好某一條ItemsSource中的某一個欄位就可以跑起來了。 但是也有另一種情況: 假設一個界面Temp.xaml ...
  • 相對於WPF/Silverlight,UWP的動畫系統可以說有大幅提高,不過本文無意深入討論這些動畫API,本文將介紹使用Shape做一些進度、等待方面的動畫,除此之外也會介紹一些相關技巧。 1. 使用StrokeDashOffset做等待提示動畫 圓形的等待提示動畫十分容易做,只要讓它旋轉就可以了 ...
  • 版權聲明:本文為原創文章,轉載請聲明http://www.cnblogs.com/unityExplorer/p/6977935.html 上一篇主要說的是protobuf位元組流的序列化和解析,將protobuf對象序列化為位元組流後雖然可以直接傳遞,但是實際在項目中卻不可能真的只是傳遞protobu ...
  • 一、死鎖的概念 多個線程的同步如果設計不當,就會造成死鎖。死鎖是指多個線程共用某些資源時,都在等待對方釋放資源,從而導致程式停滯不前的情況。 死鎖會造成程式停滯不前,所以我們在編寫多線程程式時一定要註意避免死鎖現象的發生。其實上面的問題很好解決,只要兩個線程以相同的順序訪問臨界資源即可。 設置鎖定超 ...
  • 1.Wait 用法 預設情況下,Task 是有線程池中的非同步線程執行,是否執行完成,可以通過Task的的屬性IsCompleted 來判斷, 如果想在子線程工作完成之後,在進行後續主線程工作可以通過調用task.Wait() 來等待線程完成,調用Wait 後,當前線程會被阻塞,直到到子線程完成。 代 ...
  • 第一、基本使用 Thread,ThreadPool,Task的區別 Task是.NET4.0加入的,跟線程池ThreadPool的功能類似,用Task開啟新任務時,會從線程池中調用線程,而Thread每次實例化都會創建一個新的線程。 如果是長時間的操作,請使用Task(Acton,TaskCreat ...
  • 當我們學習到一定程度的時候,我們會想要去深入瞭解代碼底層的東西,也更想擁有一個屬於自己的框架,當然,博主也正是如此。本文可能成為編寫一個webapi框架的開端。有研究MVC框架的朋友會發現,mvc框架的路由MvcRouteHandler是實現了IRouteHandler而得以實現我們路由,而IRou ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...