從微信SDK看ProtoBuffer文件的生成

来源:http://www.cnblogs.com/youngytj/archive/2016/08/03/5734234.html
-Advertisement-
Play Games

前言 Protocol Buffers (下麵簡稱PB)是一種輕便高效的結構化數據存儲格式,可以用於結構化數據串列化,很適合做數據存儲或 RPC 數據交換格式。它可用於通訊協議、數據存儲等領域的語言無關、平臺無關、可擴展的序列化結構數據格式。它支持多種語言,比如C++,Java,C ,Python, ...


前言

Protocol Buffers (下麵簡稱PB)是一種輕便高效的結構化數據存儲格式,可以用於結構化數據串列化,很適合做數據存儲或 RPC 數據交換格式。它可用於通訊協議、數據存儲等領域的語言無關、平臺無關、可擴展的序列化結構數據格式。它支持多種語言,比如C++,Java,C#,Python,JavaScript等等。目前它的最新版本是3.0.0。與PB經常相提並論的也是Google推出的FlatBuffers(下麵簡稱FB)。有關PB和FB性能和語義等方面的區別,這裡就不展開描述了。如果有興趣,可以參閱下麵的信息:

目前很多公司在一些高性能的通信場景下,會越來越多的選擇用PB或者FB來替代我們常用的Json。比如說Windows Phone的微信的SDK就用到了。

反編譯微信SDK

PB對C#官方的支持是從3.0開始的,之前的1.0和2.0的版本都能找到一些非官方的版本。我們先反編譯一下微信的SDK,看下它具體是什麼版本的。

首先,我們從微信的官網下載SDK:

Image

登陸微信開發平臺,進入資源中心,選擇WP8資源下載,點擊下載。

然後下載我們的反編譯工具ILSpy

解壓下載完成的ILSpy和SDK包,用ILSpy.exe打開MicroMsgSDK.dll。

Image

我們暫時先不管這個結構到底是怎麼來的,我們可以看到反編譯出來的文件帶了ProtoGen的版本號,我們嘗試從Github上找到這個版本號的代碼。

編譯ProtoBuffer源碼

我們先打開官方的C#版本的PB的源碼頁面:地址

可以看到官方地址只保留了3.0的版本,對於舊的2.0版本的代碼在jskeet的賬號下,

Image

我們點開這個倉庫,然後找到它的Release頁面:

Image

我們找到2.3.0.277的源碼並下載到本地。

解壓文件,我們看到Build文件夾下有一堆編譯用的腳本:

Image

雙擊運行buildAll.bat(此處應確保本機已經安裝了Visual Studio 2008及以上版本),然後等待編譯完成。

嘗試使用源碼中的Proto文件生成cs代碼

我們找到ProtoGen項目中生成的exe文件,嘗試將它放到命令行中運行:
Image

它提示我們找不到protoc.exe程式。我們回到源碼的根目錄會發現有一個lib的文件夾,裡面有一個protoc.exe的程式。所以我們嘗試吧ProtoGen項目的所有生成文件拷貝到lib下。
繼續嘗試運行我們的ProtoGen程式。

Image

這回對了,我們嘗試把源碼下的protos文件夾下的三個子文件夾拷貝到我們的lib目錄下。

我們嘗試輸入如下內容:

protogen --proto_path==protos protos/tutorial/addressbook.proto

又得到一個錯誤信息:

Image

提示我們找不到依賴,我們嘗試打開proto文件:(有關PB的語法請參閱:http://www.cnblogs.com/stephen-liu74/archive/2013/01/02/2841485.html)

package tutorial;

import "google/protobuf/csharp_options.proto";

option (google.protobuf.csharp_file_options).namespace = "Google.ProtocolBuffers.Examples.AddressBook";
option (google.protobuf.csharp_file_options).umbrella_classname = "AddressBookProtos";

option optimize_for = SPEED;

message Person {
required string name = 1;
required int32 id = 2;        // Unique ID number for this person.
optional string email = 3;

enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
}

message PhoneNumber {
    required string number = 1;
    optional PhoneType type = 2 [default = HOME];
}

repeated PhoneNumber phone = 4;
}

// Our address book file is just one of these.
message AddressBook {
repeated Person person = 1;
}

我們可以看到導入了google/protobuf/csharp_options.proto文件,我們回頭看protogen的命令參數中有一個import的標記,我們嘗試添加:

protogen --proto_path==protos protos/tutorial/addressbook.proto --include_imports=google/protobuf/csharp_options.proto

沒有任何錯誤,並且我們在lib的目錄下發現了生成的cs文件。
Image

從cs文件反推proto文件

我們打開AddressBookProtos文件,閱讀源碼發現:

  • 只有兩個非靜態類,與我們Proto文件中的Person和AddressBook對應:
    Image

  • Person類中又有一個嵌套的枚舉和類,與PhoneType和PhoneNumber對應:
    Image

  • 我們有發現,在類的IsInitialized中,Name和Id等required的有是否有值得判斷,所以我們能區分去required和optional
    Image

其他依賴信息,我們可以通過引用來查找。

從反編譯的微信文件中反推proto文件

我們以BaseReqP為例。首先,沒有using,所以我們確定沒有其他的Proto文件的依賴。我們只發現一個類,所以說明它只有一條message,名稱就是BaseReqP,然後包名是MicroMsg.sdk.protobuf。
我們知道message的所有欄位是需要標記數字的:
Image

從這裡我們又反推出,message有兩個欄位:Transaction和Type,它們類型分別是string和uint。
接下來我們推是否是必須的。找到我們的IsInitialized:
Image
從這裡我們就知道了兩個欄位都是必須的。所以綜合上述信息,我們可以寫出的proto文件如下:

package MicroMsg.sdk.protobuf;

message BaseReqP {
    required uint32 Type = 1;
    required string Transaction = 2;
}

小結

本篇內容簡要介紹了ProtoBuffer的文件如何生成C#文件,並簡單的舉例如何從C#文件反推Proto文件。

參考信息


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

-Advertisement-
Play Games
更多相關文章
  • JS DOM 來控制HTML元素 (ps:這個有很多方法,挑一些詳解,嘻嘻) 1.getElementsByName():獲取name. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~` 例:<p name="pn">hello</p> <p name="pn">hello</ ...
  • JavaScript借鑒了許多語言的特點;例如語法類Java、函數借鑒Scheme、原型繼承借鑒自Self、正則表達式借鑒於Perl。(DC Javascript:語言精粹)。 首先,每個JS是一門基於原型繼承的面向對象的語言。裡面數組是對象、函數是對象、“對象”當然還是對象。而且每個對象都有一個i ...
  • SQL:Structured Quety Language SQL SERVER是一個以客戶/伺服器(c/s)模式訪問、使用Transact-SQL語言的關係型資料庫管理子系統(RDBMS) DBMS :Database Management System資料庫管理系統 資料庫:程式用來存取數據的 ...
  • 最近因為項目原因需要在阿裡雲伺服器上部署mongodb,網上查閱了一些資料,特此記錄一下步驟 1.運行apt-get install mongodb命令安裝mongodb服務(如果提示找不到該package,說明apt-get的資源庫版本比較舊,運行apt-get update來更新資源庫) 2.安 ...
  • 在查詢分析器中執行:select rand(),可以看到結果會是類似於這樣的隨機小數:0.36361513486289558,像這樣的小數在實際應用中用得不多,一般要取隨機數都會取隨機整數。那就看下麵的兩種隨機取整數的方法:1、A:select floor(rand()*N) 生成的數是這樣的:12 ...
  • 之前介紹了Linux的Screen命令,今天介紹一個更為強大的終端工具Tmux。 Tmux 是一個用於在一個終端視窗中運行多個終端會話的工具。它基本能替代nohup以及screen,甚至比它們更為強大: Screen 的項目大體上已經終止,並且代碼中有大量的問題,使用起來很不穩定; Tmux 是一個 ...
  • 簡介: .Net中Process類功能十分強大。它可以接受程式路徑啟動程式,接受文件路徑使用預設程式打開文件,接受超鏈接自動使用預設瀏覽器打開鏈接,或者打開指定文件夾等等功能。 想要使用Process類之前,需要先引用using System.Diagnostics; Process類用法1: Pr ...
  • 一、前言 最近忙於公司的線上升級項目,一個人要負責公司四大產品的線上升級,這四個產品是在Revit中以插件形式存在的,目前基於WCF來實現。等客戶總量突破5萬了,再重新用socket實現。 由於有伺服器併發操作,所以要好好研究WCF的InstanceContext與ConCurrencyMode,找 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...