天天看點

C++中消息自動派發之三 About JSON Encode

  《C++ 消息自動派發》系列上篇介紹了IDL解析器,生成的C++代碼隻支援JSON轉C++ struct。 經過新的重構,這次增加了對C++ struct 轉JSON的支援。IDL解析器自動為C++ struct生成兩個方法。

  decode:實作json 轉C++ struct 轉。

  encode:實作C++ struct 轉json字元串。

  現實應用中,網絡伺服器程式處理流程如下:

  1> 網絡層異步接收Client消息(本文讨論的應用都是基于json協定)

  2> 對消息進行解析,如判斷消息類型,消息體字段檢查、解析、指派等。将解析完成的結果封裝到特定的struct中(每一個消息類型定義單獨一個struct)。注:JSON解析、檢查、取值都是再網絡線程完成(多線程),通常伺服器程式的核心邏輯都是在單線程中完成,故邏輯線程應重點”保護“之。待消息轉成struct後,邏輯線程直接操作二進制,盡最大程度提高邏輯線程的實時性、吞吐量。

  3> 邏輯線程處理完請求,一般會産生特定的響應結果(有時是一個,如rpc請求,有時多個,如廣播消息)。響應結果仍然要同過json協定發送給client。

  4> 邏輯成生成的響應結果為二進制struct,需要轉換成json字元串。同樣這些耗時的、與邏輯無關的操作應該放到網絡線程。道理還是一樣,盡最大程度保證

    邏輯層的效率。

  假設一個玩家查詢好友資訊接口。client發送get_friends_req請求,參數為uid,伺服器查詢該user的好友,生成好友清單list,傳回消息結果。

  首先定義IDL檔案,其中有兩個消息體:

     對應的伺服器實作代碼如下所示,稍微做些解釋:

  1> socket_t 封裝linux socket 檔案描述符操作,這裡隻是個示例,其提供async_write接口,使用preactor模式發送資料。其接受所有消息的基類指針,并且該指針為智能指針,無需手動析構。消息體基類支援encode接口,講二進制struct轉成json字元串,socket則将json字元串通過write系統調用發送給client。

  2> logic_service_t 邏輯層,處理所有的消息請求。針對每一個消息定義重載一個handle函數,為了避免網絡層消息傳到邏輯層的記憶體拷貝,這裡使用智能指針,同時避免了手動管理。

  3> msg_dispather_t, 這個類是由idl 解析器自動生成的,在生産環境,應該有網絡層調用此對象。由于本文隻是示例,故忽略網絡層,由main模拟網絡層調用。

  

  idl_generator.py  example.idl msg_def.h

  前面定義的example.idl 經過idl_generator.py 分析後生成頭檔案msg_def.h, 其中包括 msg_dispather_t 的實作,其主要代碼為:

  通過不斷開發IDL解析器,進一步優化了json的解析和編碼。其中:

  1> json_instream.h 完成json的decode,依次周遊struct中的字段,為其指派。json_instream_t中重載了支援所有類型參數的decode參數。

  2> json_outstream.h 完成struct 轉json,依次周遊struct中的字段,将其轉為json value,其重載了支援所有基本類型的encode參數。

  示例代碼:

   1. IDL 解析器已經實作了基本功能,下次準備利用此IDL 解析器實作一個聊天伺服器。

   2. IDL 解析器添加對二進制encode/decode的支援。