? ? 最近一直在開發(fā)通過ble進行設(shè)備與App交互的產(chǎn)品。在開發(fā)過程中,手機一直作為中央設(shè)備,負責主動發(fā)起掃描連接,而設(shè)備作為邊緣設(shè)備。需求需要兩者發(fā)送指令,傳輸文件。文件的傳輸就是將設(shè)備中的文件拆解成一包一包的數(shù)據(jù)通過ble發(fā)送給App。在設(shè)備與App定義了一套通用的協(xié)議的基礎(chǔ)上,兩者的指令發(fā)送很正常,因為指令的發(fā)送簡短而且單一,雙方處理沒有問題。但是在發(fā)送文件時,遇到了嚴重的丟包問題。當時設(shè)置的設(shè)備發(fā)送數(shù)據(jù)到App,拆分的數(shù)據(jù)包大小是180個字節(jié),這在iphone6s上已經(jīng)達到上限了。但是在發(fā)送文件時,App上接受的數(shù)據(jù)會出現(xiàn)丟包,首先懷疑的是設(shè)備端沒有將數(shù)據(jù)發(fā)送出來,后來設(shè)備端改了發(fā)送邏輯,在每一包數(shù)據(jù)發(fā)送之后,在收到底層的發(fā)送成功回調(diào)之后再發(fā)送下一包數(shù)據(jù),在這種模式下,App端接受到的數(shù)據(jù)還是會丟。當時問題很困擾,App端覺得是設(shè)備端的問題,設(shè)備端覺得是App端的問題。后來我想到了一種場景,在那種場景的啟發(fā)下,我覺得現(xiàn)在這種場景是之前那種場景的反向。
? ? 之前我在做一款AI 語音耳機時,也是通過ble傳輸實時音頻以及進行OTA(固件升級)的。當時在傳輸OTA數(shù)據(jù)包時,由于耳機的內(nèi)存不夠,在我一直發(fā)送文件包時,耳機會crash,后來固件排查下來由于內(nèi)存不夠,在瘋狂發(fā)送數(shù)據(jù)時,把內(nèi)存撐爆了,導致了耳機的奔潰,最后的解決方案是我對發(fā)送的每一包數(shù)據(jù)都設(shè)置了合適的長度外,還在每一包的發(fā)送過程中進行sleep,給固件時間去進行處理,這樣問題就解決了。
? ? 然后我聯(lián)想到這次的問題,由于不同的手機采用的藍牙芯片參差不齊,不同的藍牙芯片的處理能力又不同,所以我懷疑在固件瘋狂發(fā)送數(shù)據(jù)到手機上時,根據(jù)不同手機的藍牙芯片的處理能力,會出現(xiàn)丟包的大小也不一樣。針對這種懷疑,我們測試了iphone6s,iphonex,iphone11,發(fā)現(xiàn)后兩臺設(shè)備的丟包率明顯小很多。我們又測試了不同價位的Android手機,也發(fā)現(xiàn)低端Android手機的丟包率也明顯大于中高端手機。在基于這種測試基礎(chǔ)上,提出了解決方案:1.降低每個數(shù)據(jù)包的大小,2.每個數(shù)據(jù)包間隔時間發(fā)送,這個時間需要測試。在經(jīng)過測試之后,單純第一點解決方案和第二點解決方案都不會達到最理想的結(jié)果,所以合適的方案就是兩者結(jié)合,將丟包率降到更低。所以最終的解決方案就是降低每一包的大小的同時,也保證每包數(shù)據(jù)包的發(fā)送間隔,這兩者的數(shù)據(jù)我們是通過測試之后拿到的平衡值,針對不同的固件的藍牙芯片這個數(shù)據(jù)可能都是不同的。
? ? 兜兜轉(zhuǎn)轉(zhuǎn)了一圈查到了丟包問題的原因,其實這個原因不難想,我跟固件開發(fā)當時都覺得是對方處理的問題,導致一直沒有從全局去看這個問題,記錄一下。