網易技術乾貨 | 雲信跨平臺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

https://chromium.googlesource.com/chromium/src/+/master/docs/windows_build_instructions.md

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++泛型編程與模板元編程要求較高

Google git :https://chromium.googlesource.com/chromium

  • Boost

資料文檔豐富,支持我們所需的各種平臺,代碼還算簡捷,可以有選擇的引入庫,有些功能需要配合其它三方庫來完善,使用起來與STL相差不大

Boost Trachttps://svn.boost.org/trac10/

  • Poco

資料文檔豐富,支持我們所需的各種平臺,代碼簡捷,從功能上來說比較全

POCO c++libraryhttp://pocoproject.org/

POCO docs: http://poco.sourcearchive.com/

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. 傳送門

邀請好友使用網易雲信,好友下單成功即可獲得500元網易考拉/嚴選無門檻現金券,點擊立即推薦>>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章