網易技術乾貨 | 雲信跨平臺C++ SDK開發實戰

1. 序 言

2018年,Flutter Release正式發佈,將移動端跨平臺開發技術再一次推上風口浪尖。2019年5月,Flutter 1.5正式支持Web開發,而預告中正在開發的Flutter for Desktop以及對於嵌入式的支持,使得Flutter最終目標將再也不是移動框架,而是一個跨平臺、多平臺框架。再往前推數年,RN、小程序已是移動端生產開發中常見的跨平臺開發技術,Electron、Qt也逐漸成爲當前桌面端跨平臺應用的首選技術方案。
綜上所述,在客戶端一次編寫,多處運行的大趨勢下,底層SDK服務能力的跨平臺化、多平臺化就顯得更爲重要和天然。
雲信SDK提供有iOS/OSX、AOS、Windows、Linux、Unity等常見平臺的支持,從長期的開發維護中獲得的經驗,咱們認爲底層能力的跨平臺化應該解決以下痛點:
  1. SDK接口在各平臺上不統一,包括接口的命名、傳參,對外部開發者不友好。
  2. SDK功能在各平臺上由不一樣團隊維護,需求須要反覆溝通保障實現上的統一,使得產品迭代速度很慢。
  3. 若是團隊之間沒有有效的溝通,面對一樣的需求和能力,不一樣的實現方案,測試團隊每每須要設計不一樣的測試用例,下降了產品迭代效率。
固然,跨平臺開發也有一些不足,好比跨平臺代碼每每須要引入第三方庫,不如原平生臺編寫的代碼精簡,遇到與設備相關的邏輯,仍是避免不了須要採用原生代碼編寫插件的形式來提供能力等等。

2. 架構介紹

網易雲信C++ SDK目前還只支持Windows平臺,架構設計以下圖:
  • third patry:引入的三方庫。
  • 組件層:SDK開發框架的根基,提供對通訊套接字、本地緩存、加/解密、線程模型、日誌等基礎功能組件,並對引入的三方庫進行二次封裝。
  • SDK業務實現層:包含了全部SDK業務邏輯的實現,SDK內部線程的管理等。
  • SDK接口層:對外暴露SDK各功能接口並提供c++封裝層
nbase整合自chromium開源項目中的一部分,是長期支撐雲信Windows客戶端SDK的基礎庫,包含了基本框架Messageloops,閉包,基本函數庫(file、network等),基本類庫(time,線程,定時器等),基本工具庫(log,加解密)等,功能豐富,可是目前僅支持和適配了Windows平臺,並不能很好的支撐其餘平臺的開發,所以改進和改造nbase模塊是咱們跨平臺開發過程當中最早考慮的。

3. 跨平臺改造

nbase模塊與SDK的實現已深度的耦合,這次改造咱們提出瞭如下幾個目標:
  1. 對上層業務代碼最少的改動,最好是不要改動。
  2. 可方便更換跨平臺框架,雖然咱們選擇了Chromium base做爲咱們開發框架,可是有可能會隨着Chromium的迭代而對跨平臺框架進行升級/降級,或者爲知足特殊設備改用其它跨平臺方案。
基於以上兩點考慮,咱們把原來nbase模塊抽象爲框架適配層,將引入的跨平臺框架進行隔離,nbase模塊再也不實現任務具體功能,只是對跨平臺框架的二次封裝,在最大程度上減小上層代碼的改動。
改造後的結構圖:

4. 改造之路

4.1. 規範化編碼
除了遵循Google cppguide外咱們還整理了與咱們SDK開發相關的一些規則:
  1. 頭文件: 爲了不某些編譯器編譯失敗,包含的頭文件不能使用‘\’,必須所有使用‘/’,不要使用#pragma once ,使用#ifndef _XXX_H_ #define _XXX_H_ #endif,頭文件目錄必須從頂層目錄開始,好比’core/core/nim_core.h’。
  2. 命名空間: [namespace]_BEGIN_DECLS/[namespace]_END_DECLS/ USING_NS_[namespace] 替換原先的命名空間定義。
  3. 導出API/類: XXX_EXPORT,導出的類和函數都要加上這個宏。
  4. 規範系統定義: OS_WIN/OS_MAC/OS_LINUX/OS_ANDROID/OS_IOS儘可能不要直接使用系統自帶的宏 好比WIN32。
  5. 規範各平臺實現的區別: 經過文件後綴來區分,好比 platform_device_win.cpp、 platform_device_android.cpp等。
  6. 字符串編碼格式的標準化: 使用 std::string/UTF8String/UTF16String/UTF32String。
4.2. base庫的編譯
參考官方文檔Checking out and Building Chromium for Windows
chromium原生採用的是Ninja的腳本編譯,咱們並無進行直接的生成,而是選擇自行搭建Visual Studio/XCode項目,這樣作的目有兩個:
  1. 方便集成到咱們的工程調試,在開發過程當中常常會碰到這樣那樣的問題,因此調試是必不可少的步驟。
  2. 爲了後續對base庫的精簡和可控打下基礎。
目前支持的平臺是Windows/IOS/MacOS三個平臺的編譯,Android/Linux在後續安排開發。編譯步驟基本就是建立新項目,把全部代碼文件加入到項目,而後再剔除非該平臺的代碼文件,各平臺都適用這步驟。
4.3. extention庫
前面提到把原來nbase模塊抽象爲框架適配層,咱們料想到這個過程沒法在一個迭代週期內完成,因此採用分批適配的方式來進行,因而咱們又定義了extension庫(同屬nbase命名空間)來對nbase庫進行抽象,同時對base庫的一些功能進行外圍補充補充。
4.4. 對windows xp的支持
自2014年4月8日以後,微軟再也不提供 Windows XP技術幫助,但並不表明用戶能夠立刻升級到新的windows操做系統,尤爲咱們的SDK可能會用於多個行業,對於某些行業用戶來講支持Windows XP是硬性需求,通過幾回討論後,咱們發現目前還不能夠放棄Windows XP系統,前面提到,咱們選擇使用Chromium base (v71.0.3578.98)作爲咱們跨平臺開發框架,而支持Windows XP系統的chromium版本是「49.0.2623.112」,得益於nbase庫抽象爲框架適配層,跨平臺開發框架很快的切換到了chromium 49版本。在編譯支持XP版本時咱們須要設定如下幾個配置:
  • Windows SDK 改成使用7.0
  • WINVER = 0x0501
  • PSAPI_VERSION = 1

5. 經驗分享

網易雲信目前已經開發完成並上線了跨平臺C SDK,從一開始的開發跨平臺C SDK到現在的對C++ SDK的跨平臺改造,開發小組也接觸了許多C++開發領域常見並熟識的跨平臺基礎庫,例如stl、boost、Poco、folly等,內部也對幾個基礎庫作過詳細的對比,首先根據咱們的SDK業務需求,以及對平臺的需求,若是咱們作到跨平臺須要知足如下幾個最基本的需求:
Facebook 的 folly庫應該也是個很好的選擇,但因爲時間關係沒有去整理,看介紹,這個庫爲了效率重造了不少輪子,估計會有不少詭異的實現,因此並未進入對比範圍。
  • chromium base + net
資料文檔較少,支持咱們所需的各類平臺,代碼較複雜,完整的base庫較大,使用或修改對C++泛型編程與模板元編程要求較高
  • Boost
資料文檔豐富,支持咱們所需的各類平臺,代碼還算簡捷,能夠有選擇的引入庫,有些功能須要配合其它三方庫來完善,使用起來與STL相差不大
Boost Trac: svn.boost.org/trac10/
  • Poco
資料文檔豐富,支持咱們所需的各類平臺,代碼簡捷,從功能上來講比較全
POCO c++library: pocoproject.org/

6. TO DO

目前,雲信跨平臺SDK已經支持Windows(xp+)、OSX、iOS平臺,咱們計劃2019年Q4完成對Linux部分桌面發行版的開發支持工做,2020年Q1完成對AOS的開發支持工做,後期也會增長對常見的小型設備的開發支持工做。此外,爲了方便開發者快速接入SDK,咱們將在2019年Q4上線基於跨平臺SDK封裝的ElectronSDK,2020年上半年上線FlutterSDK。
跨平臺SDK自己不少組件或思想來自於開源社區,將來咱們計劃開源跨平臺開發框架,經過回饋開源社區,但願繼續與社區一塊兒打造好玩的「輪子」,你們能夠先關注https://github.com/netease-im/phoenix。開源該技術提升了產品團隊與開發者之間的透明度,有助於跨平臺開發的普及,並使開發者可以參與並對這些開源技術作出持續貢獻。
最後,感謝曾經以及現在還在爲網易雲信跨平臺SDK貢獻代碼的小夥伴們,包括但不限於rg,gg, harrison等等大佬們。

7. 傳送門

相關文章
相關標籤/搜索