聊天功能的完整實現


最近做的項目又牽扯到聊天功能(此處發誓我們不是做社交的!),雖然網頁聊天和手機應用不大一樣,還是想要理一理及時聊天的解題思路,大家可以參考這個模型,自我感覺結構是完整了但有點複雜,非常歡迎任何形式的探討。
先放張效果圖:


chat


接下來會把聊天功能的實現分成兩個部分來解釋,這一篇主要是數據在客戶端和服務器之間傳輸過程;另個篇主要講講我怎麼設計並區分聊天過程中消息的不同狀態的(三個狀態:正在發送,發送成功,發送失敗,而這張圖裏貌似沒有- -)。
用戶第一次打開App的時候網絡層已經向服務器發起長鏈接,並且服務器查數據庫將新消息返回給客戶端,客戶端將新數據保存到本地數據庫。
用戶第一次進入某個聊天狀態的時候,業務層取出本地數據庫的聊天數據,並將一些聊天相關的數據保存在內存,以便隨時顯示和更改。由於服務器和客戶端的數據庫狀態要保持一致(網頁聊天就不用了,因爲每次都是重新向服務器請求所有聊天記錄,除非網頁有做緩存。App就不得行,你沒網就也要讓人家看到歷史記錄),所以需要把當前聊天的最後一條已讀消息ID發給服務器記錄。初始化了數據,就啓用一個定時器線程來刷新界面,間隔40ms刷新一次,一般用戶是感覺不到的。

FirstReq


用戶這個時候要發消息了!
A編輯好內容,點擊發送按鈕想要發給B,客戶端程序先把數據存入本地數據庫,然後再將數據加入聊天界面顯示的列表(記着:刷新界面的線程還在定時工作呢!),此時消息狀態應該還處於正在發送中。
開啓一個異步任務——發送這條消息到服務器,服務器在保存數據後,需要返回這條記錄的ID(問我爲什麼?上面說了啥,別忘要有兩端數據庫狀態的一致性檢驗哦!)
接着還不忙返回發送成功的喜訊,服務器先看看B在不在線,如果正巧也在線,就將消息打包立刻發送出去(這裏修改了sentflag值,爲了表明消息已經發送到B)。
不管B在不在線都要返回發送成功的喜訊啦,客戶端收到喜訊就將對應消息的狀態改爲發送成功,如果由於網絡故障等原因,導致一段時間沒有返回喜訊,客戶端就將對應消息的狀態改爲發送失敗(當然,你也可以一直讓狀態保持在正在發送,這樣做省事但有點反人類)。

SendMsg

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