一種自動反射訊息類型的 Google Protobuf 網路傳輸方案

來源:互聯網
上載者:User

這篇文章要解決的問題是:在接收到 protobuf 資料之後,如何自動建立具體的 Protobuf Message 對象 ,再做的還原序列化。“自動”的意思是:當程式中新增一個 protobuf Message 類型時,這部分代碼不 需要 修改,不需要自己去註冊訊息類型。其實,Google Protobuf 本身具有很強的反射(reflection)功能, 可以 根據 type name 建立具體類型的 Message 對象,我們直接利用即可。

本文假定讀者瞭解 Google Protocol Buffers 是什麼,這不是一篇 protobuf 入門教程。

本文以 C++ 語言舉例,其他語 言估計 有類似的解法,歡迎補充。

本文的範例程式碼在: https://github.com/chenshuo/recipes/tree/master/protobuf

網路編程中使用 protobuf 的兩個問題

Google Protocol Buffers (Protobuf) 是一款非常優秀的庫,它定義了一種緊湊的可擴充二進位消 息格 式,特別適合網路資料轉送。它為多種語言提供 binding,大大方便了分布式程式的開發,讓系統不再 局限 於用某一種語言來編寫。

在網路編程中使用 protobuf 需要解決兩個問題:

長度,protobuf 打包的資料沒有內建長度資訊或終結符,需要由應用程式自己在發生和接收的時候 做正 確的切分;

類型,protobuf 打包的資料沒有內建類型資訊,需要由發送方把類型資訊傳給給接收方,接收方創 建具 體的 Protobuf Message 對象,再做的還原序列化。

第一個很好解決,通常的做法是在每個訊息前面加個固定長度的 length header,例如我在 《Muduo 網 絡編程樣本之二: Boost.Asio 的聊天伺服器》 中實現的 LengthHeaderCodec,代碼見 http://code.google.com/p/muduo/source/browse/trunk/examples/asio/chat/codec.h

第二個問題其實也很好解決,Protobuf 對此有內建的支援。但是奇怪的是,從網上簡單搜尋的情況 看, 我發現了很多山寨的做法。

山寨做法

以下均為在 protobuf data 之前加上 header,header 中包含 int length 和類型資訊。類型資訊 的山 寨做法主要有兩種:

在 header 中放 int typeId,接收方用 switch-case 來選擇對應的訊息類型和處理函數;

在 header 中放 string typeName,接收方用 look-up table 來選擇對應的訊息類型和處理函數。

這兩種做法都有問題。

第一種做法要求保持 typeId 的唯一性,它和 protobuf message type 一 一對應。如果 protobuf message 的使用範圍不廣,比如接收方和發送方都是自己維護的程式,那麼 typeId 的唯一性不難保證,用版本管理工具即可。如果 protobuf message 的使用範圍很大,比如全公司都在 用, 而且不同部門開發的分布式程式可能相互連信,那麼就需要一個公司內部的全域機構來分配 typeId, 每次增 加新 message type 都要去註冊一下,比較麻煩。

第二種做法稍好一點。typeName 的唯一性比 較好 辦,因為可以加上 package name(也就是用 message 的 fully qualified type name),各個部門事 先分 好 namespace,不會衝突與重複。但是每次新增訊息類型的時候都要去手工修改 look-up table 的初 始化代 碼,比較麻煩。

其實,不需要自己重新發明輪子,protobuf 本身已經內建瞭解決方案。

根據 type name 反射自動建立 Message 對象

Google Protobuf 本身具有很強的反射(reflection)功能,可以根據 type name 建立具體類型的 Message 對象。但是奇怪的是,其官方教程裡沒有明確提及這個用法,我估計還有很多人不知道這個用 法, 所以覺得值得寫這篇 blog 談一談。

以下是陳碩繪製的 Protobuf  class diagram。

相關文章

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。