HarmonyOS分布式協同演奏技術實現路線(Java)
一、寫在前面的話
分布式能力是鴻蒙的一大亮點,不管是分布式數據庫,還是分布式文件管理,抑或是分布式任務流轉,都給我們日常的使用習慣帶來很大的變革。很多時候我就在想,我們還能怎樣應用分布式呢?百思不得其解之時,愛因斯坦的小提琴就莫名其妙地浮現在了腦海里。音樂!一個好的樂隊、好的樂團,不正是由一個個小的部分組成的嗎?于是,自由樂隊就蘊育而出了。
本文將重點講述下自由樂隊分布式協同演奏的技術實現路線,重點講的是思路,講的不好的地方還請大家多多包涵。
二、路線一
采用監聽數據庫的方法實現組網間設備的協同演奏。
主要流程如上圖,核心就是分布式狀態數據庫和分布式音樂演奏數據庫,通過監聽這兩個數據庫實現組網間設備的組隊和協同演奏功能。分布式狀態數據庫用于組隊信息的傳輸,分布式協同演奏數據庫用于樂器模擬按鍵信息的傳輸。
1、分布式音樂演奏數據庫的初始化
如下圖,我們軟件初始化的時候就會創建屬于該設備的DeviceKvStore,并對其進行監聽。
同時,我們在DataAbility里有個deviceKvStores用來保存deviceId和DeviceKvStore的對應關系。
2、判斷是否為本地端
如下圖,我們采用通過intent攜帶的關鍵字來判斷是否為本地端。
本地端調起協同端時,寫入該關鍵字:
3、點擊事件的處理
如下圖,當監聽到點擊事件發生的時候,統一調用DataAbility.clickSound(),為防止阻塞,我們使用異步調用的方式。
而DataAbility.clickSound()則會通過DeviceId獲取到DeviceKvStore,同時將按鍵點擊事件的mSrc(即相應按鍵的ID)寫入。
?4、DeviceKvStore數據庫的監聽
如下圖,首先會判斷是否為本地端,若為本地端則處理點擊事件。處理點擊事件的核心就是獲取到點擊按鍵的mSrc,首先通過notification.getDeviceId()獲取到DeviceId,然后通過DeviceId去獲取響應的DeviceKvStore,然后通過key來拿到mSrc,進而調用DataAbility.playClip()。DataAbility.playClip()就是模擬樂器演奏的相關函數。
?5、分布式狀態數據庫的初始化
6、分布式狀態數據庫的監聽
核心就是獲取此時退出隊伍設備的DeviceId,若當前設備為本地端,則停止對該設備進行監聽,同時彈出該設備退出隊伍的提示;若當前設備為協同端,同時發起退出設備的DeviceId為當前隊伍的本地端,則表示該隊伍已解散,當前設備變為本地端,同時彈出隊伍已解散的提示。
值得一提的是,分布式狀態數據庫是所有設備初始化的時候都通過DataAbility.STATE_KEY來監聽同一個分布式狀態數據庫DeviceKvStore,而分布式音樂演奏數據庫則是每個設備都會根據自己唯一的DataAbility.storeId來創建分布式音樂演奏數據庫DeviceKvStore,也就是說會有多個分布式音樂演奏數據庫。
因此,我們是在DataAbility里通過deviceKvStores來儲存DeviceId和DeviceKvStore的對應關系。組隊的實質就是實現對相應分布式音樂演奏數據庫的監聽。多個DeviceKvStore就能夠實例化多個KvStoreObserver來對多個數據庫進行監聽,并行進行處理,減少并發帶來的影響,降低協同演奏的延時。
7、協同演奏模擬樂器
協同端和本地端一樣,當監聽到點擊事件的時候,也是調用DataAbility.clickSound()。同樣在DataAbility.clickSound()里通過DeviceId獲取DeviceKvStore,然后將按鍵點擊事件的mSrc寫入相應的DeviceKvStore分布式數據庫。
不同的是協同端的KvStoreObserver雖然監聽到了數據變化,但是判斷當前設備為協同端,則不會去進行模擬樂器演奏的播放。而此時,組隊本地端也同時監聽到了數據變化,進而去進行模擬樂器演奏的播放。
三、路線二
我們想到的第二種實現分布式協同演奏的方法就是類似于Codelabs里面的分布式游戲手柄的寫法(鏈接在文末),本地端調起協同端的時候通過IAbilityConnection進行連接。同時,協同端通過proxy.senDataToRemote()將按鍵信息發送給本地端,本地端通過onRemoteRequest()來處理協同端發來的信息。詳細講解可以參考Codelabs里面的代碼,同時有一些包也在Demo里面封裝好了,可以不用重復造輪子。
具體代碼實現我之前測試的時候都寫好了。BUT,因為太卡了,我們就放棄了這條路線,代碼也給回退了。(也可能是我們的水平有限,代碼優化的不是很好)我們當時是先寫的通過訂閱分布式數據庫來實現協同演奏的,但是我最開始是只通過訂閱一個單板本分布式數據庫實現的協同演奏,感覺效果不太理想,就嘗試了路線二。嘗試了之后發現,路線二還沒有之前的延遲小呢,就最終確定了采用路線一,同時后面又對路線一進行了相關的優化,比如采用訂閱分布式狀態數據庫和多個分布式音樂演奏數據庫、異步處理點擊事件、線程阻塞等等技術來降低延遲,最終實現了至少三個設備(當時手上只有三個設備)可以協同演奏一首曲子的程度。
四、總結
協同演奏的實現路線我們研究了兩條,分別是監聽數據庫和直接建立連接。兩者都可以實現功能,但是協同演奏很重要的一點就是延遲,延遲太大就真的只能聽個響了。個人覺得,就目前來看,鴻蒙在分布式減少延遲這塊還是有很長的路要走的。
Codelabs:??分布式游戲手柄(Java)??。