? ? ? ?最近在做直播間的聊天室,踩了很多坑,我們采用的是融云的IM,實(shí)現(xiàn)聊天室的功能,所有的直播間功能都通過消息進(jìn)行傳遞,如,禮物、紅包、連麥、踢人、彈幕、禁言、管理...等等。對(duì)于這些消息的處理就出現(xiàn)了一些問題,下面我將介紹我踩坑的過程和解決的過程。
一、采用融云的消息處理
? ? ? ? 融云其實(shí)對(duì)大并發(fā)消息做了一些處理,在接收消息的地方融云返回了一個(gè)nleft表示剩余消息條數(shù),他們建議當(dāng)nleft 等于0的時(shí)候我們?cè)谌ニ⑿耈I,這樣可以避免過多消息處理導(dǎo)致主線程阻塞,內(nèi)存升高,最終有可能導(dǎo)致APP閃退。我采用的他們的處理方式,但是我的消息不只是普通的文字聊天消息可以在等消息接收完去刷新tableView,我還有禮物播放的消息,連麥消息,它們的優(yōu)先級(jí)都很高需要實(shí)時(shí)進(jìn)行刷新,按照剛才的處理方法就有問題,并且還會(huì)出現(xiàn)消息丟失的問題,如禮物連續(xù)發(fā)送的時(shí)候消息并發(fā)量大,就會(huì)導(dǎo)致發(fā)送方和接受方禮物的個(gè)數(shù)不一致,內(nèi)存過大。
二、定時(shí)取消息并刷新視圖
? ? ? ? 由于上面的情況,后面查閱了很多資料想出了一種方法就是定時(shí)取消息并處理刷新,這種方法就是創(chuàng)建一個(gè)消息的緩存池,將接收來的所有消息先存放到緩存池中,然后定時(shí)0.5秒或者1秒去緩存中拿一條消息去處理并刷新UI,后來測(cè)試發(fā)現(xiàn)高并發(fā)下內(nèi)存增長不是太高,整體比較流暢,而且也解決了高并發(fā)消息丟失的問題,但是這種處理又引發(fā)了另一個(gè)問題就是我們的緩存池相當(dāng)于一個(gè)隊(duì)列,遵守先進(jìn)先出的原則,所有接收的消息都需要排隊(duì)去處理,這就造成有些即時(shí)性比較高的消息需要等待前面的消息處理完才能處理當(dāng)前的消息,造成消息延遲過大。
三、按優(yōu)先級(jí)緩存消息,定時(shí)去取
? ? ? ? ?基于上述情況 ,我對(duì)所有的消息的優(yōu)先級(jí)進(jìn)行分類,先按即時(shí)性分,再按消息量分,對(duì)所有的消息我分了五個(gè)等級(jí)。
1.連麥、關(guān)注、踢人、禁言消息量少即時(shí)性高放到優(yōu)先級(jí)一級(jí);
2.紅包、進(jìn)場(chǎng)、退場(chǎng)消息量比較大即時(shí)性也高放到第二等級(jí);
3.小禮物消息量大消息即時(shí)性要求不是很大放到第三等級(jí);
4.普通文本消息量特別大即時(shí)性不是很高放到第四等級(jí);
5.彈幕,公告,系統(tǒng)消息消息量不是很大即時(shí)性也不是很高第五等級(jí);
? ? ? ? 對(duì)于這五個(gè)等級(jí)消息去取,我采用一秒鐘取消息的次數(shù)劃分等級(jí),而且每個(gè)時(shí)刻只取某一個(gè)緩存池的一條消息,優(yōu)先級(jí)一一秒鐘取9~11次,優(yōu)先級(jí)二取6~8次,優(yōu)先級(jí)三取4~5次,優(yōu)先級(jí)四取2~3次,優(yōu)先級(jí)五取1次,通過這種處理解決了上述消息的即時(shí)性的問題,實(shí)際測(cè)試中也看到了效果,高并發(fā)也不會(huì)造成內(nèi)存增高,消息丟失的問題。
四、總結(jié)? ? ?
? ? ? ? 通過這次的消息處理,降低了CPU的處理,優(yōu)化了系統(tǒng)性能,提高了用戶體驗(yàn)問題,但是這只是初步的處理,其實(shí)還有很多優(yōu)化的地方,比如定時(shí)取每個(gè)等級(jí)消息的時(shí)間,我們后期可以做成動(dòng)態(tài)的,根據(jù)當(dāng)前房間人數(shù)可以動(dòng)態(tài)調(diào)整時(shí)間,人數(shù)越多,時(shí)間可以適當(dāng)變短或者其他方式,消息的處理還可以采用多線程處理,并行執(zhí)行,提高執(zhí)行效率,等等這些優(yōu)化。