我為什么要再給lua寫一個json模塊


  最近要給自己編寫的服務器加上json解析模塊。根據我當前的項目,可以預測服務器中使用json的地方:

  • 通信。由於與客戶端通信使用google protocolbuffer,僅在與SDK通信中使用json
  • 配置。我們當前直接將配置轉換為lua table。但其他項目依然有很大概率要使用json作為配置。
  • MongoDB。項目中使用MongoDB作為數據存儲,很多接口需要用到json.

而在我的服務器中,寫了一個MongoDB lua driver,可以直接將lua table轉換為MongoDB的bson數據結構,DB這塊不需要json了。像配置都是靜態數據,一次加載后不會再加載了。而SDK通信也僅限於登錄充值,相對來說對json的效率要求不是很高。

  由於服務器底層以C++為主,上層為lua,當然是先查找lua的json模塊。在http://lua-users.org/wiki/JsonModules上,列出了主流的lua json模塊。但是常用的也就lua4json和mp-cjson兩個。lua4json是我們現在使用的,每一個玩家存庫,都要將lua table轉為json再傳給MongoDB接口。從目前來看,性能還是可以的,而且是純lua。mp-cjson貌似是cocos2dx標配的json解析模塊,底層是基於cjson的,效率高,用的人也多。

  對於lua而言,傳統的數組和關聯數據都是lua table,要轉為json時就要做一些判斷才能知道是array還是object。我希望是這樣的:

  • 如果key都是int,則是數組。而如果key不是從1開始,則是稀疏數組(sparse array)。
  • 允許通過元表指定是array還是object。如果指定為object,則所有key會被轉換為string。如果指定為array而key中包含float、string則使用自增的int做key。

  lua4json是不能指定是array還是object的,並且嘗試將key為float等也轉換為array。因此一個空的lua table( {} )只能由lua4json的作者定死為array。這對於從lua寫進數據庫,從lua讀出來也不是太大的問題。但在實際使用中發現,如果你嘗試在Mongo Shell中做些操作或者用java寫的后台讀取數據時,就有點麻煩了。不過json4lua是純lua的,我改改就可以用了。在最后進行測試時,解析從https://github.com/miloyip/nativejson-benchmark中下載的一個2M多的json串,花了7分多鍾。結果,我放棄了,萬一哪天策划給我來個8M的配置表,我開個服務器豈不得用半個鍾。

  mp-cjson我看了一下api(http://www.kyne.com.au/~mark/software/lua-cjson-manual.html),有一個encode_sparse_array函數可以處理sparse array,但也沒有可以強制指定array、object的函數。

  在泛型語言與強類型語言交互的時候,確定類型很重要。比如我有這樣一個lua table:

local reply = 
{
    array_item = {},
    map_id     = {}
}

現在我要將他轉換為json存到MongoDB或者發送到java后台,json串應該是

{ "array_item":[],"map_id":{} }

上面的兩個庫,沒有一個做得到。於是我決定自己寫一個lua的json模塊。

  自己再寫基礎的json解析是不太可能的了。我決定使用小巧的parson,然后給他加上lua的粘合層,就可以成為lua的模塊了,命名為lua_parson。我定了比較詳細的規則:

  • 如果key值都為int並且小於INT_MAX,必定為數組。
  • 如果在元表指定__array並且值為true,則必定為數組
  • 如果是數組並且key都為int,則為sparse array,空位直接使用null填充
  • 如果1、2兩點不成立,則必為object。object中所有不為string的key都將直接轉換為string

  現在這個庫放在https://github.com/changnet/lua_parson。安裝使用也比較簡單。注意這個庫不是線程安全的。

  我自己以前也覺得不要重復造輪子,但現在覺得別人的輪子並不是那么好用。雖然實際情況項目中,上面列出的極端情況還沒出現過,那些庫也可以將就者用。即使出現了,也可以換種方法解決。但如果可以完美一點,為什么不去做呢?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM