
組成
http網(wǎng)關(guān):認(rèn)證、負(fù)載均衡
網(wǎng)絡(luò)接入層:維持長(zhǎng)連接,接收、推送消息
業(yè)務(wù)服務(wù)層:聊天業(yè)務(wù)相關(guān)的消息處理服務(wù)
redis消息管道:銜接網(wǎng)絡(luò)接入層和業(yè)務(wù)服務(wù)層間的內(nèi)存型消息管道。網(wǎng)絡(luò)接入層server和業(yè)務(wù)服務(wù)層的service實(shí)例1:1,server實(shí)例在redis里有一個(gè)對(duì)應(yīng)的上行管道,用于server向service推送消息,service處理完后,將加工后的消息加入到目標(biāo)server的下行管道
redis緩存,內(nèi)容:
1、組織、群組、連接映射
2、在線用戶的最近會(huì)話、最新消息數(shù)、待ACK列表、收發(fā)箱
mongodb:存儲(chǔ)最近一月的消息,便于快速獲取一月以內(nèi)的離線消息
mysql:按組織id分庫(kù),所有讀都從從庫(kù)讀,需要保證主從同步質(zhì)量
認(rèn)證
1、user1和user2通過(guò)網(wǎng)關(guān)認(rèn)證以及按uid均衡
2、認(rèn)證成功后,網(wǎng)關(guān)返回token,和用戶相關(guān)的組織信息、群關(guān)系、最近會(huì)話、最新消息數(shù)
3、以客戶端上次獲取消息的最晚時(shí)間戳,如果沒(méi)有該時(shí)間戳,則用上次登錄時(shí)間戳為準(zhǔn),異步初始化用戶的最近一月內(nèi)的離線消息
連接
1、根據(jù)網(wǎng)關(guān)的均衡情況,user1和serverA建立連接,user2和serverB建立連接,
2、server對(duì)user的token進(jìn)行校驗(yàn)
3、通過(guò)校驗(yàn)的user,server更新連接映射表到redis緩存,否則直接close連接
4、推送離線消息
聊天消息
1、user1向user2發(fā)聊天消息,serverA收消息后進(jìn)行基本的協(xié)議、防攻擊、去重校驗(yàn),指定消息序號(hào)、然后pub到redis管道
2、業(yè)務(wù)處理層sub到聊天消息,將消息發(fā)布到kafka,更新待user2 的ack列表、最新消息數(shù),同時(shí)將添加序號(hào)的消息和對(duì)user1的ACK pub到redis管道
3、serverA接收到業(yè)務(wù)處理層pub的ack消息,將ack推送給user1;serverB接收到業(yè)務(wù)處理層pub的消息,直接推送給user2
4、user2接收到serverB推送的聊天消息后,向serverB 發(fā)送ack
5、serverB接收到user2的ack,更新待user2的ack列表
信令消息
1、user1離群,離群操作的信令消息從客戶端發(fā)往serverA,經(jīng)過(guò)redis消息管道推向業(yè)務(wù)服務(wù)A
2、業(yè)務(wù)服務(wù)A原子更新mysql主庫(kù),redis緩存的群組關(guān)系,向redis消息管道推送發(fā)給user1的ack,向群內(nèi)所有在線人員推送的更新群成員信令消息,更新待ack消息列表
3、user1接收到ack,所有在線成員接收到更新群成員信令,更新本地群成員并返回ack
4、服務(wù)接入層接收到ack,更新待ack列表