W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
之前的一些文章簡(jiǎn)單介紹了《“單人消息”》《“離線消息”》《“群消息”》《“用戶狀態(tài)”》的一些相關(guān)技術(shù)(點(diǎn)擊上面的link直接閱讀),今天來(lái)聊一聊“多點(diǎn)登陸”與“消息漫游”。
提問(wèn):什么是多點(diǎn)登錄?
回答:以微信為例,可以PC端,phone端同時(shí)登錄,同時(shí)收發(fā)消息。
需要注意的是,一個(gè)端只能登錄一個(gè)實(shí)例,例如同一個(gè)QQ號(hào),在pc1上登錄,再到pc2上登錄,后者會(huì)把前者踢出,pc1會(huì)收到通知“你已在別處登錄xxoo”。
提問(wèn):什么是消息漫游?
回答:在任何一個(gè)終端的任何一個(gè)實(shí)例登錄qq,都能夠拉取到所有歷史聊天消息,這個(gè)就是消息漫游。
微信目前只支持“多點(diǎn)登錄”同時(shí)收發(fā)在線消息,沒(méi)有實(shí)現(xiàn)“消息漫游”,潛臺(tái)詞是:登出手機(jī)微信,登錄PC微信,聊天,再登錄手機(jī)微信,是看不到歷史消息的。
整個(gè)即時(shí)通訊架構(gòu)可以抽象成這么幾層:
(1)客戶端:例如pc微信,手機(jī)qq
(2)服務(wù)端:
(2.1)入口層gate集群:能夠水平擴(kuò)展,保持與客戶端的連接
(2.2)邏輯層logic、路由層router集群:高可用可擴(kuò)展,實(shí)現(xiàn)業(yè)務(wù)邏輯,進(jìn)行消息的路由
(2.3)cache:高可用cache集群,用來(lái)存儲(chǔ)用戶的在線狀態(tài),與接入節(jié)點(diǎn)(用戶具體連接在哪個(gè)gate節(jié)點(diǎn))
(2.4)db:固化存儲(chǔ)消息,群信息,好友關(guān)系鏈等信息
一個(gè)典型的消息投遞流程如上圖步驟1-5:
(1)用戶A登錄在gate1上,發(fā)出消息
(2)gate1將消息給logic/router
(3)logic/router查詢接收方的在線狀態(tài)(B在線,C不在線)
(4)例如接收方C不在線,存儲(chǔ)離線
(4)例如接收方B在線,且登錄在gate2上,消息投遞給gate2
(5)gate2將消息投遞給B
當(dāng)然,單對(duì)單消息有一系列應(yīng)用層超時(shí)、重傳、確認(rèn)、去重的機(jī)制,這不是本文的重點(diǎn),不進(jìn)行展開(kāi),細(xì)節(jié)詳見(jiàn)《微信為什么不丟消息》。
接收方多點(diǎn)登錄,pc也登錄,phone也登錄,后一端登錄不會(huì)將前一端踢出,cache中存儲(chǔ)狀態(tài)與登錄點(diǎn)時(shí),不再以u(píng)ser_id為key,改為以u(píng)ser_id+終端類(lèi)型為key即可。
B:online(狀態(tài)),gate2(登錄點(diǎn))
改為
B+pc:online(狀態(tài)),gate2(登錄點(diǎn))
B+phone:online(狀態(tài)),gate3(登錄點(diǎn))
有朋友可能要問(wèn),發(fā)送方和多點(diǎn)登錄有什么關(guān)系?
假設(shè)用戶A登錄了兩個(gè)點(diǎn),A1和A2;用戶B登錄了兩個(gè)點(diǎn)B1和B2
A(A1發(fā)出的)發(fā)送消息給B(B1和B2)
B(B1發(fā)出的)發(fā)送消息給A(A1和A2)
不就可以了么?
其實(shí)不然,A(A1發(fā)出的)發(fā)送消息給B(B1和B2),B(B1發(fā)出的)發(fā)送消息給A(A1和A2)
A2端雖然收到了所有B回復(fù)的消息,但消息其實(shí)是在A1端發(fā)出的,故A2端只知道聊天消息的一半(所有B的回復(fù)),缺失了聊天的上下文(所有A1端的發(fā)出)
故,如果發(fā)送方也進(jìn)行了多點(diǎn)登錄,發(fā)送出去的任何消息,除了要投遞給多點(diǎn)登錄的接收方,還需要投遞給多點(diǎn)登錄的發(fā)送方。
如上圖,發(fā)送方A和接收方B都進(jìn)行了多點(diǎn)登陸,cache中存儲(chǔ)的信息為:
A+pc:online(狀態(tài)),gate0(登錄點(diǎn))
A+phone:online(狀態(tài)),gate1(登錄點(diǎn))
B+pc:online(狀態(tài)),gate2(登錄點(diǎn))
B+phone:online(狀態(tài)),gate3(登錄點(diǎn))
當(dāng)用戶A(phone端)給用戶B發(fā)送消息時(shí),除了要投遞給B的所有多點(diǎn)登錄端,還需要投遞給A多點(diǎn)登陸的其他端(pc端),如上圖中步驟4與步驟5。
只有這樣,才能在所有用戶的所有端,恢復(fù)與還原雙方聊天的上下文。
如果業(yè)務(wù)不需要支持“消息漫游”的功能,對(duì)于在線消息,如果用戶接收到,是不需要存儲(chǔ)到數(shù)據(jù)庫(kù)的。但如果要支持“換一臺(tái)機(jī)器也能看到歷史的聊天消息”,就需要對(duì)所有消息進(jìn)行存儲(chǔ)了。
消息投遞如上圖,用戶A發(fā)送消息給用戶B,雖然B在線,仍然要增加一個(gè)步驟2.5,在投遞之前進(jìn)行存儲(chǔ),以備B的其他端登陸時(shí),可以拉取到歷史消息。
消息拉取如上圖,原本不在線的B(phone端),又重新登錄了,ta怎么拉取歷史消息?只需要在客戶端本地存儲(chǔ)一個(gè)上一次拉取到的msg_id(time),到服務(wù)端重新拉取即可。
這里還有個(gè)問(wèn)題,由于服務(wù)端存儲(chǔ)所有消息成本是非常高的,所以一般“消息漫游”是有時(shí)間(或者消息數(shù))限制,不能拉取所有所有幾年前的歷史消息,只能拉取3個(gè)月內(nèi)的云端消息。
“多點(diǎn)登錄”是指多個(gè)端同時(shí)登錄一個(gè)帳號(hào),同時(shí)收發(fā)消息,關(guān)鍵點(diǎn)是:
(1)需要在服務(wù)端存儲(chǔ)同一個(gè)用戶多個(gè)端的狀態(tài)與登陸點(diǎn)
(2)發(fā)出消息時(shí),要對(duì)發(fā)送方的多端與接收端的多端,都進(jìn)行消息投遞
“消息漫游”是指一個(gè)用戶在任何端,都可以拉取到歷史消息,關(guān)鍵點(diǎn)是:
(1)所有消息存儲(chǔ)在云端
(2)每個(gè)端本地存儲(chǔ)last_msg_id,在登錄時(shí)可以到云端同步歷史消息
(3)云端存儲(chǔ)所有消息成本較高,一般會(huì)對(duì)歷史消息時(shí)間(或者條數(shù))進(jìn)行限制
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: