客戶(hù)端和服務(wù)器建立長(zhǎng)連接之后,需要發(fā)送業(yè)務(wù)信息。由于網(wǎng)絡(luò)不是十分穩(wěn)定,連接不能保證暢通,發(fā)送消息不一定能到對(duì)方。這時(shí)候怎么辦??
一種情況服務(wù)器把消息發(fā)送出去,默認(rèn)這條消息客戶(hù)端一定能收到,具體客戶(hù)端是否真能收到,服務(wù)器不管。顯然這種處理方式不對(duì)?。?! 第二種情況服務(wù)器把消息發(fā)送出去,服務(wù)器記錄這條消息的狀態(tài),客戶(hù)端如果收到這條消息,向服務(wù)器發(fā)送一個(gè)回執(zhí),服務(wù)器收到這個(gè)回執(zhí)將狀態(tài)修改成已經(jīng)收到,如果一定時(shí)間沒(méi)有收到回執(zhí),則再次發(fā)送這條消息。
消息就需要重發(fā)?重發(fā)幾次呢??等等一系列的問(wèn)題。 服務(wù)端維護(hù)一個(gè)正在發(fā)消息的隊(duì)列,服務(wù)端向客戶(hù)端推送消息后,收到客戶(hù)端的回執(zhí),把響應(yīng)的消息從隊(duì)列中移除。服務(wù)器20s之后會(huì)輪詢(xún)這個(gè)消息隊(duì)列,把消息隊(duì)列中已經(jīng)發(fā)送的消息但是沒(méi)有收到回執(zhí)的消息再次發(fā)送一遍。 如果同一條消息被發(fā)送了5次,一直沒(méi)有收到回執(zhí),則認(rèn)為服務(wù)器與客戶(hù)端保持的這個(gè)長(zhǎng)連接已經(jīng)斷開(kāi)了,但是由于某種原因服務(wù)器沒(méi)有把這個(gè)長(zhǎng)連接關(guān)閉掉,這種情況服務(wù)器則把這個(gè)長(zhǎng)連接對(duì)象channel關(guān)閉、釋放掉資源。
如果客戶(hù)端與服務(wù)器保持的長(zhǎng)連接對(duì)象channel關(guān)閉掉,則需要處理“正在發(fā)消息的隊(duì)列”對(duì)象,將屬于這個(gè)鏈接的消息持久化到數(shù)據(jù)庫(kù)中。這樣做也是為了節(jié)約內(nèi)容開(kāi)支,都已經(jīng)判斷這個(gè)長(zhǎng)連接失效了,就沒(méi)有必要再次想它推送消息了。當(dāng)下次再建立這個(gè)客戶(hù)端的長(zhǎng)連接的時(shí)候我們首先在數(shù)據(jù)庫(kù)中查詢(xún)時(shí)候有屬于它的未發(fā)送消息,如果有未發(fā)送消息,則進(jìn)行發(fā)送。。 服務(wù)器向客戶(hù)端發(fā)送消息1次,客戶(hù)端向服務(wù)器發(fā)送這條消息的回執(zhí)。 服務(wù)器由于網(wǎng)絡(luò)原因沒(méi)有收到回執(zhí),這條消息的回執(zhí)丟了,服務(wù)器會(huì)再把這條消息發(fā)送第二次,客戶(hù)端這次會(huì)收到重復(fù)的消息,這時(shí)候客戶(hù)端怎么處理呢??繼續(xù)顯示這條消息顯然不正確,客戶(hù)端需要驗(yàn)證這條消息是否收到,進(jìn)行合法性進(jìn)行驗(yàn)證。這里需要用到消息唯一標(biāo)示。 對(duì)于上面客戶(hù)端重復(fù)收到服務(wù)器推送過(guò)來(lái)的消息,魅族架構(gòu)師是這么解決的,我直接引用原文相關(guān)的部分: |
|
來(lái)自: WindySky > 《即時(shí)通訊》