周江华:网易云信IM推送保障及网络优化实践
周江華,網(wǎng)易資深Android開發(fā)工程師,先后主導參與了易信、網(wǎng)易云信、網(wǎng)易七魚的客戶端開發(fā)工作,擁有非常豐富的功能開發(fā)以及代碼優(yōu)化經(jīng)驗。
2016年9月23日,MDCC 2016中國移動開發(fā)者大會在北京國家會議中心如期開幕。會上,網(wǎng)易云信Android端高級技術架構師周江華,發(fā)布了題為“云信IM推送保障及網(wǎng)絡優(yōu)化實踐”的主題演講,與所有開發(fā)者共同分享了網(wǎng)易云信IM在應對弱網(wǎng)環(huán)境、移動端硬件限制以及Android復雜的生態(tài)現(xiàn)狀時的探索與心得。
演講主題: 《云信 IM 推送保障及網(wǎng)絡優(yōu)化實踐》
主題介紹: 在復雜的 Android 生態(tài)環(huán)境下,多種因素都會造成消息推送不能及時達到客戶端。另外,不穩(wěn)定的移動網(wǎng)絡也給數(shù)據(jù)傳輸?shù)乃俾屎涂煽啃栽黾恿苏系K。
本文從這兩個方面出發(fā),講述了網(wǎng)易云信 IM SDK 如何實現(xiàn)不影響用戶體驗的后臺?;?#xff0c;改善的長連接加推送組合方案,以及在弱網(wǎng)環(huán)境大數(shù)據(jù)傳輸?shù)膬?yōu)化實踐。
演講筆記:云小信 ?深度好文:7980 字 | 20 分鐘閱讀
閱讀筆記先看問題:
1.什么是IM
2.云信 IM SDK如何實現(xiàn)不影響用戶體驗的后臺保活
3.如何做長連接加推送組合方案
4.如何在弱網(wǎng)環(huán)境下優(yōu)化大數(shù)據(jù)傳輸
完整筆記
對于移動APP來說,IM功能正變得越來越重要,它能夠創(chuàng)建起人與人之間的連接。社交類產(chǎn)品中,用戶與用戶之間的溝通可以產(chǎn)生出更好的用戶粘性。
IM是什么,有些什么要求呢?IM由兩個字組成:Instant,Messaging。
即時性要求有新消息時能夠立即收到,如果程序在后臺,則要能立即收到推送通知。
通信則要求穩(wěn)定可靠,系統(tǒng)不宕機,程序不崩潰,安全,傳遞消息時不會被攔截監(jiān)聽,消息不丟,順序不亂,不重復,如果包含音視頻聊天,則要求延遲低,流暢不卡頓。
要真正做出一套穩(wěn)定可靠的商用級IM系統(tǒng),挑戰(zhàn)非常之多。下面,我會挑選影響IM即時性和消息穩(wěn)定性最核心的兩個問題,來看看都有哪些障礙,以及云信是如何去實踐克服這些障礙的。
第一個問題是消息推送。iOS有 APNS做推送,相當穩(wěn)定。Android本身也有GCM可以用,但是在國內(nèi)有“墻”,直接就把GCM等等google的服務全部擋在外面。為了實現(xiàn)即時穩(wěn)定的消息推送,從易信時代開始,我們就開始研究,隨著時間的推移,困難和方法也在不停的變化。
對于IM,當APP退到后臺,是必須還能夠收到新消息提醒的,沒有GCM,怎么辦?在最初,唯一能做的,就是后臺運行了。這幾乎是接收推送的唯一途徑,就算是到現(xiàn)在,也是最主要的途徑。Android從設計上,就是支持真后臺運行的,后臺運行的特性也是Android現(xiàn)在能如此成功的原因之一,但另一面,Android長久以來一直擺脫不了的卡頓,耗電等壞名聲,后臺運行也拖不了干系。因此,系統(tǒng)對于后臺運行也不會放任自流。APP想要在后臺運行,需要面對不少的障礙。
第一個障礙是Android的Low Memory Killer機制。手機的內(nèi)存有限,當后臺運行的進程越來越多,內(nèi)存剩余量也就隨之減少。當有一個新的APP想要啟動,如果內(nèi)存不夠,LMK機制就會啟動,從正在運行的進程中挑選一個清理掉,釋放出空間,然后新的APP就可以運行了。
LMK有兩個尺度去評判。一個是進程優(yōu)先級,優(yōu)先級越低,被清理的可能性越大,另一個是內(nèi)存占用,占的內(nèi)存越多,被清理的權重自然也越大。
因為LMK機制的存在,雖然APP允許在后臺運行,但同樣也面臨隨時被清理的風險。因此,我們需要在被清理后及時的重新啟動。常規(guī)的,有4種方式能夠做到。
第一個是sticky service,就是在Service的onStartCommand中返回sticky flag,這樣當service被kill掉后,系統(tǒng)會將它加入重啟的pending列表,在后面合適的時機再把service重啟。
第二個是alarm,鬧鐘,有循環(huán)鬧鐘和一次性鬧鐘兩種,在鬧鐘觸發(fā)后啟動對應的組件。
第三個是在Manifest文件中靜態(tài)注冊的Receiver,通過監(jiān)聽各種系統(tǒng)事件,比如開機,網(wǎng)絡變化,mount/unmounts等,在這些事件發(fā)生時啟動組件,因為這種方式會造成在這些事件發(fā)生時系統(tǒng)容易卡頓,在7.0里面,Android增加了限制。
第四個是JobScheduler,這是在5.0里面新增的,允許APP在特定事件發(fā)生時做一些動作,比如充電,切換到wifi等。
雖說無論怎么做,APP終究免不了一死,但通過對照LMK的評判準則,我們還是可以降低APP被清理的概率的。第一個就是降低進程的內(nèi)存占用。如果采用單進程的模式,由于進程中包含了UI,Webview,各種圖片緩存等內(nèi)容,內(nèi)存必然會居高不下,降不下來。IM軟件一般都會采用雙進程甚至多進程的策略,將push進程獨立出來,在push進程里只處理網(wǎng)絡連接和push業(yè)務,不參與任何其他業(yè)務邏輯,更不包含任何UI。
這是云信Android SDK的架構,按照分層的結構模式設計。最底下青色的一層是push層,他就是作為一個獨立進程運行的。他只負責處理網(wǎng)絡長連接的相關工作,比如安全加密,心跳,鑒權,封包解包等工作,所有業(yè)務邏輯都交給UI進程的服務模塊去做。我們來看一下云信demo的進程內(nèi)存占用情況。上面一個是主進程,看第四列PSS的數(shù)據(jù),內(nèi)存占用是50M左右,下面一個是push進程,內(nèi)存占用只有10M左右。當處于后臺時,push進程被清理概率比UI主進程低很多。
降低被清理概率的第二個手段是提升進程優(yōu)先級。我們先看這個例子,這是綠色守護的一個截圖,我不想去評價其他APP的行為,也不想打廣告,所以這里對icon和名字做了模糊處理。我們看最上面,這一組是“暫不自動休眠”,因為這里列出的兩個APP的狀態(tài)都是工作中,對應的進程優(yōu)先級是“可視進程”。但這兩個APP并沒有提供桌面小部門在運行,也沒有指示前臺服務的常駐通知欄提醒,事實上,他們就只是在后臺運而已。通常進程退到后臺后,其進程優(yōu)先級類型就變成了較低的后臺進程,而不是這樣的“可視進程”,他們是通過什么方法來提升優(yōu)先級,今兒降低被清理概率的呢?
Android在設計前臺服務上有一個漏洞,通過兩個服務配合,我們就能創(chuàng)建一個隱形的前臺服務。這里有兩個已經(jīng)啟動的service: A和B。先在A中調(diào)用startForeground,提供一個NOTIFY_ID, 然后A就變成前臺服務了,同時有了一個ID為NOTIFY_ID的常駐通知欄提醒,然后我們在B中也調(diào)用startForeground,提供相同的NOTIFY_ID, B也變成了前臺服務,因為兩個通知ID相同,因此這一次就不會創(chuàng)建新的通知欄提醒了。然后再在A中調(diào)用stopForeground,A的前臺屬性被取消,同時,常駐通知欄提醒也會被移除,但是,service B并不會受到任何影響,還是前臺服務,這是再把A停掉,進程就只剩下前臺服務B了,進程也變成了前臺進程,但用戶不會有任何感知。
正常來說,做了上面3步之后,我們的進程就能夠比較穩(wěn)定的在后臺運行了。但是后來我們發(fā)現(xiàn),在有些情況下,我們的推送進程卻永遠起不來。
跟蹤之后,我們發(fā)現(xiàn),除了系統(tǒng)能夠殺掉后臺運行的進程外,用戶也一樣是可以殺死進程的。用戶殺掉進程的方式有兩種,一種是在最近任務列表中將app劃掉,這種方式和系統(tǒng)殺掉進程效果相同。另外一種就是通過這里的force stop,這種方式比系統(tǒng)清理更加徹底。不但app正在運行的進程會被清理,app當前在重啟列表中的待重啟服務,注冊的各種鬧鐘,事件監(jiān)聽組件等都會被移除,除非用戶在主動點擊或者系統(tǒng)重啟等外力,app沒法再自己重新爬起來了。
我們后來還發(fā)現(xiàn),在有些國內(nèi)的像MIUI一類的ROM上,用戶從最近任務列表中將app移除,效果竟然也是force stop。正常來說,如果是用戶主動操作,我們app本身也不應該再重啟了。但有些時候這個并不是用戶本意,況且,對于IM軟件來說,消息推送是一定要得到保障的,否則不明正確的吃瓜群眾們會覺得是我們軟件不行,連消息推送都做不好。因此,這時候我們還是應該想辦法繼續(xù)維持后臺運行。
那么,我們又有哪些辦法呢?
?
第一個是通過兩次fork加上exec的方式。兩個fork后,第一次fork的進程退出,第二次fork出來的進程就會被init進程領養(yǎng)。用戶此時再force stop,因為這個進程父進程是init,而不是Zygote,因此不會被清理。由于這個進程還是從android進程fork出來的,帶有android運行時環(huán)境以及父進程的資源,所以內(nèi)存會比較大,這里可以再通過exec命令,打開一個純linux的可執(zhí)行文件,開啟一個daemon進程,其內(nèi)存占用大概只有100K+,對用戶也就完全無感了。利用這個后臺進程,可以定時的將push進程拉起來。此種方式只在5.0以下的系統(tǒng)中有效,在4.4及以上系統(tǒng)中,SELinux特性是強制開啟的,exec沒有權限執(zhí)行,同時在5.0之后,ActivityManager在做force stop以及移除任務時,只要是具有相同的uid的進程,就會全部清理掉,不再漏掉沒有虛擬機環(huán)境的進程。
?
最后一個后臺?;畹氖侄问且粋€大殺器,也是帶有強烈的中國特色。因為前面所列的所有?;钍侄味疾皇悄敲幢kU,因此想出來這么一個互相?;畹姆绞?。當一個APP進程起來后,他就去掃描已安裝的應用列表,看看有沒有自己的兄弟姐妹,比如說同一個長的APP,或者是集成了同一個SDK的APP,如果有,就把這些APP都拉起來。這也就是現(xiàn)在比較出名的“全家桶”方案。雖說這種方法確實能夠帶來較高的后臺存活率,特別是那些大廠和應用廣泛的sdk,但是這種方式對于用戶的傷害也非常大,如果有后臺推送的必要性,且不會對用戶體驗造成太大傷害時,此方式還可以使用,但如果只是為了推廣告,則會對用戶造成傷害,反過來,也可能會導致用戶直接卸載APP。
現(xiàn)在,因為全家桶實在是太令人討厭,現(xiàn)在各種手機管理軟件都會對這種喚醒方式做限制,特別是在root過的機器上,可以做到完全切斷這些喚醒路徑。同時,很多ROM也會自帶管理軟件,限制后臺運行和后臺喚醒,以便給設備換取更長的續(xù)航。在目前國內(nèi)的Android生態(tài)環(huán)境中,無論采用什么方式,想要一直在后臺運行時越來越難了,我們需要重新想另外的辦法來保障消息推送。另一方面,我們作為開發(fā)者,也有義務為用戶提供更好體驗的軟件,而不是無休止的在后臺浪費用戶的資源。
其實,對于IM來說,及時的消息推送和較低的電量消耗也并非不可兼得。在傳統(tǒng)上,每個IM客戶端都會各自維護一條與服務器的長連接,自己的消息和信令都在這條長連接上傳遞,每個APP也獨自去心跳,斷線重連等事情。
這種模式比較簡單,不同的APP也是完全隔離的,不會互相影響。但他的缺點也非常明顯,首先是做了很多重復的事情,造成了流量和電量的無謂消耗;第二是要保證所有的進程都能在后臺運行很難。優(yōu)化的方向也就非常明顯了,那就是共享連接,現(xiàn)在絕大部分推送SDK也是這么做的。從這些APP里面選出一個當前正在運行的,或者是被殺概率最低的APP作為總代理,只由這個代理和服務器建立連接,一個手機上的所有其他APP都通過這個代理中轉與服務器通信。但是,IM有一個很基本的要求在這種模式下無法得到滿足:安全。所有APP的消息都經(jīng)過代理中轉,代理到服務器的連接是加密的,安全的,但到了代理這里,消息都被解開了,因此代理理論上可以看到其他所有APP的來往消息。因此,這種共享長連接的方式并不適用于IM。
雖然共享長連接方式不合適,但仍然給我們提供了一個優(yōu)化的思路。在此基礎上,我們想到了另外一個可以脫敏共享連接的方式:安全長連接加推送連接模式。
每個APP在使用和真正傳遞數(shù)據(jù)時,仍然獨立使用自己的安全長連接。而當APP退到后臺一段時間之后,則斷開長連接,然后每個APP開啟一個推送代理,并選擇其中一個和云信的推送服務器建立連接,之后當APP有新消息時,就通過這個推送連接傳遞。APP可以自己控制發(fā)出的推送消息的安全級別,可以是包含說話人和消息內(nèi)容,可以只包含說話人,或者只是一條簡單的有新消息到達的提醒文案。推送到達后,如果是代理APP自己的消息,直接傳遞給代理APP即可。如果是其他APP消息,前面說到過,直接喚醒可能會失敗,而且會導致無謂的電量消耗,所以這里并不直接將提醒傳遞給目標APP,而是由帶來發(fā)出一條通知欄提醒。等用戶去點擊通知欄提醒后,才會把目標APP喚醒。
現(xiàn)在國內(nèi)的ROM中,華為和小米的系統(tǒng)本來是帶有推送系統(tǒng),且開放給了第三方APP的。在這兩個系統(tǒng)上,使用系統(tǒng)的推送通道明顯會更加穩(wěn)定,也更加節(jié)省資源。因此在MIUI上,從長連接到推送通道的切換流程仍然和前面的一樣,只是不再使用自己的推送連接,而是將消息轉發(fā)到MIUI的推送服務器,然后轉給MIUI系統(tǒng)的推送代理,然后傳遞給云信的APP。華為的推送系統(tǒng)流程也是一樣。不過現(xiàn)在華為和MIUI在推送實現(xiàn)上有一些區(qū)別,例如MIUI的通知欄提醒是在自己的推送代理里完成的,而華為卻是將提醒通知交給APP自己去完成的,另外,他們的通知欄提醒的管理接口也有很多區(qū)別。在APP沒有被禁用的情況下,兩者都可以收到推送,而如果APP已經(jīng)被禁用了,MIUI的通知欄提醒方式還可以將推送送達,而其他的推送方式則不能送達了。
以上就是在保障消息推送方面我們所能夠做的所有事情了。如果以后有更多的系統(tǒng)開放自己的推送系統(tǒng),我們也可以選擇逐步接入,以提高推送到達即時性,減少資源消耗。不過相應的,我們也要承受不斷加入各種系統(tǒng)的推送SDK,增大發(fā)布包體積的缺點。期望Android擁有統(tǒng)一推送平臺的那一天早點到來吧。
相對于PC的網(wǎng)絡環(huán)境,我總結的手機網(wǎng)絡有3個特點:
第一個是慢,尤其是2G,3G網(wǎng)絡,慢的令人發(fā)指。當我們收發(fā)圖片視頻這類比較大的文件時,就會看到蛋疼的菊花一圈一圈不停的轉。
第二個是斷,手機跟著人不停的移動,網(wǎng)絡也不停的在切換,從wifi到移動網(wǎng)絡,從一個基站到另一個基站,從有信號到?jīng)]信號,都可能導致網(wǎng)絡中斷。有些制式的網(wǎng)絡,接打電話也會導致數(shù)據(jù)網(wǎng)絡斷開。另外,移動基站還有NAT超時,到一個連接上長時間空閑后,基站就會默默的將連接斷開,沒有任何通知。
第三個是貴,這個就不用多說,看中國移動每天凈賺一個億就知道了。
在云信整個通信系統(tǒng)中,我們有3種類型的連接:TCP,UDP,HTTP。雖說這三個并不是同一層的協(xié)議,不過畢竟都在我們的應用的更下層,因此這么劃分也無妨。3種類型的協(xié)議對應了不同的業(yè)務應用。TCP主要是用戶長連接,也就是普通IM消息和信令的傳輸,UDP用于傳輸實時音視頻數(shù)據(jù)流,而HTTP則主要用在音頻,圖片等文件的上傳下載上。對于不同的業(yè)務,我們的優(yōu)化的關注點會有一些不相同。
長連接是云信所有業(yè)務的基礎,使用量也是最大的,因此優(yōu)化也是從基礎開始。 在這里我們舉兩個例子。
第一個是協(xié)議的選擇。前面說,長連接的使用量是最大,選擇一個合適的協(xié)議至關重要。如果是剛開始接觸IM開發(fā),一般會選擇一些開源的協(xié)議,比如XMPP,SIP等。這是XMPP協(xié)議的一個請求樣例,可以看到是一段XML格式的文本數(shù)據(jù)。這是基于SIP的SIMPLE協(xié)議的一個請求樣例,可以看到是一段類似HTTP協(xié)議的文本數(shù)據(jù)。這些協(xié)議的優(yōu)勢在于開源,有成熟的解決方案可以使用,擴展性好,甚至還可以和其他系統(tǒng)互聯(lián)互通,協(xié)議的可讀性也非常好。但是在普遍比較臃腫,冗余字段很多,在昂貴的移動網(wǎng)絡里面用起來會讓人覺肉疼。云信采用的是私有的二進制協(xié)議,這是一個請求的數(shù)據(jù)樣例,這里是把二進制數(shù)據(jù)轉為了16進制顯示出來,每個字節(jié)這里顯示為兩個字符??梢钥吹蕉M制協(xié)議的特點在于完全失去了可讀性,但是,卻帶來極高的表達效率,相對于文本協(xié)議,可以節(jié)省非常多的數(shù)據(jù)流量。
另一個例子是登錄的優(yōu)化。由于移動網(wǎng)絡經(jīng)常斷開,所以登錄常常是心跳之外交互最多的協(xié)議了。使用量越大,優(yōu)化就越有意義。一般而言,登錄會經(jīng)過這么幾步。
第一步是LBS。這里的LBS不是經(jīng)常說的基于地址位置的服務,在不同的廠商可能也有不同的叫法,反正作用都是獲取服務器的IP地址。像云信這種需要提供全球服務的系統(tǒng),在世界各地都要部署服務器,用戶登錄時,肯定要選擇一臺最優(yōu)的服務器接入服務。通過lbs,客戶端可以獲取離自己最近,連通性最好的服務器連接機IP地址,服務器也可以據(jù)此做負載均衡。
拿到服務器連接機IP后,客戶端就去連接該服務器。
連接成功,需要有一次握手。這個握手不是TCP的三次握手,而是為了建立安全連接,同服務器協(xié)商加密算法和加密密鑰。
然后就發(fā)送登錄請求,這里會帶上用戶認證信息,本機設備信息等數(shù)據(jù)。
登錄成功之后,就是同步數(shù)據(jù),包括離線消息,用戶信息,群組信息等。一般而言,這里不會去做全量同步,而是采用基于時間戳的增量同步。
在移動網(wǎng)絡上,每一次交互都需要比較長的時間,同時,每一次網(wǎng)絡請求電量消耗也是很大的。所以,優(yōu)化的方向就是盡量減少交互次數(shù),而方法則是合并請求,并行操作以及省略請求。
LBS和連接這兩個步驟是可以并行完成的。如果前面已經(jīng)獲取過LBS,這里可以有之前的緩存地址,如果沒有,可以先連一個默認地址。
其次是握手和登錄也可以并行操作。在握手包中,就可以把加密后的登錄包直接帶上去了。如果是斷線重連,我們還可以簡化登錄,直接帶上上一次登錄的會話ID,一來減少服務器鑒權壓力,二則可以直接帶回在斷線期間是否有未讀消息等數(shù)據(jù),如果沒有,則能直接將同步這一步省略掉。如果有,同步也可以只做部分同步,只去拉去離線消息即可。等到APP切換到前臺,才去同步其他的信息。
通過這些優(yōu)化,登錄時間可以降為原來的1/2到1/3,登錄的流量消耗也可以節(jié)省30%左右。
實時音視頻對實時性要求很高,但可以容忍一定的丟包,所以我們選擇UDP私有協(xié)議來做為底層的傳輸協(xié)議。如果只是普通的IM消息,對網(wǎng)絡情況其實不是太敏感,最多也就是慢一點,菊花轉的久一點。但對于這種視頻電話,如果網(wǎng)絡差了,發(fā)生了經(jīng)常性卡頓,或者是延遲很高,圖像出現(xiàn)花屏,音視頻不同步了,這個功能其實也就相當于廢棄了。而且,音視頻數(shù)據(jù)量本身也比較大,在弱網(wǎng)環(huán)境下發(fā)生問題的概率就更大了。
?
UDP協(xié)議是不可靠,為了提高弱網(wǎng)下的實時音視頻的通話效果,需要使用相關方案來做QoS保障:主要包括了基于udp協(xié)議的擁塞控制、前向糾錯FEC技術及相關的重傳技術。同時網(wǎng)絡層需要能夠實時的探測到網(wǎng)絡狀態(tài),作為底層調(diào)整QoS策略的依據(jù),同時需要回調(diào)上層,來動態(tài)調(diào)整音視頻的碼率,做到音視頻碼率自適應。通過上面的QoS保障,我們實際測試在20%的隨機丟包弱網(wǎng)環(huán)境下,音視頻通話還能夠正常進行。
第二是音頻,我們的音頻編解碼主要以Opus為主,它具備高音質,高壓縮率,高抗丟包等特性,非常適合移動網(wǎng)絡。我們使用智能的jitterbuffer算法來平滑由于網(wǎng)絡抖動引起的聲音卡頓和延遲累計問題。配合PLC丟包補償算法,來降低音頻丟包后的爆音。同時,我們使用自研的高性能降噪算法,配合回聲消除、自動增益和舒適噪音等音頻處理算法來進一步保證音頻部分的質量。
對于視頻,我們使用時域分層的H264視頻編碼器,來降低丟包對視頻流暢性的影響,同時支持動態(tài)幀率和動態(tài)分辨率,方便上層根據(jù)業(yè)務需求進行切換?,F(xiàn)在用戶對于視頻的清晰度要求越來越高,我們的實時通話系統(tǒng)當前能夠支持720p。720p下純軟件編解碼對CPU開銷過大,因此在可以開啟硬件編解碼的機器上,對于需要720p清晰度的都盡量使用硬件編解碼。
由于音視頻的網(wǎng)絡優(yōu)化如果全部細說,恐怕再加1個小時也講不完,所以這里我只提了一些優(yōu)化的方向供大家參考,就不一一展開了。
下面再來看看對于HTTP的優(yōu)化。圖片語音是IM的必需元素,而且本身數(shù)據(jù)比較大。在弱網(wǎng)環(huán)境下,快速的上傳下載,更少的等待時間可以帶來更好的用戶體驗。
斷點續(xù)傳可以減少因網(wǎng)絡原因導致的重復傳輸,減少傳輸時間,節(jié)省流量。
圖片預加載技術可以根據(jù)不用網(wǎng)絡情況,在收到消息后,就加載不同素質的預覽圖片,甚至直接將原圖預加載,做到用戶點開即看。
上面兩個是比較基礎的優(yōu)化措施,下面兩個則比較高級一點。
圖片和語音這種文件我們并沒有通過長連接收發(fā),而是通過HTTP去做上傳下載。傳統(tǒng)上通過HTTP上傳時,文件會分為一片一片,傳完一片,收到回包,才會穿下一個分片,一直到最終傳輸完成??梢钥吹?#xff0c;服務器返回ack這段時間,上傳通道其實是空閑的,如果把這段時間利用起來,可以節(jié)約不少上傳時間。Pipeline就是為此而來。通過重疊利用http請求的響應等待時間,加快傳輸速度。使用pipeline,需要修改HttpClient,同時還需要服務器提供支持。視網(wǎng)絡具體情況,使用pipeline后,一次上傳可以減少20%至30%的時間。
常規(guī)發(fā)送語音消息需要這幾步,先錄音,然后計算hash值,然后上傳,上傳完畢后,服務器計算一下校驗和,通過后語音消息發(fā)送成功。在前面錄制語音時,網(wǎng)絡其實也是空閑的。把這段時間利用起來,則可以減少后面上傳步驟的時間。優(yōu)化后,流程就變成這樣。在錄制的過程中,每錄完一段,就作為一個分片直接上傳。直到最后錄完,計算好hash,再把最后一個分片帶上hash信息上傳。這里除了客戶端的改動,也是需要服務器支持。服務器在開始接收時,很多信息都不明確,需要開辟緩存來記錄整次上傳過程。對于比較差的網(wǎng)絡,邊錄邊傳的效果會更好,畢竟純語音的比特率并不高,基本都能做到錄完就傳完。
以上就是分享的全部內(nèi)容。提升消息推送達到率和到達速度,優(yōu)化網(wǎng)絡利用效率,節(jié)省系統(tǒng)資源一直都是Android開發(fā)的核心和基礎,新技術,新方法都在不停的涌現(xiàn),也歡迎大家一起討論,進步。
【推薦閱讀】
吳桐:連麥互動直播方案全實踐
闕杭寧:通過IM云讓開發(fā)者共享網(wǎng)易經(jīng)驗
周梁偉:聊天室架構如何跳出傳統(tǒng)思維來設計
項望烽:移動IM開發(fā)那些事兒
總結
以上是生活随笔為你收集整理的周江华:网易云信IM推送保障及网络优化实践的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【InfoQ大咖说直播回放】老司机聊程序
- 下一篇: CSDN专访云信阙杭宁:以16年技术积累