推送消息是通過 Apple 和 Google 掌控的互聯(lián)網(wǎng)服務(wù)器發(fā)送的,推送消息從根本上就是設(shè)計(jì)用于與應(yīng)用程序通信的,它們可以發(fā)送文本、多媒體文件和特定于應(yīng)用程序的數(shù)據(jù)。那么,消息推送的的設(shè)計(jì)原理和規(guī)則是什么?
隨著 iPhone 和安卓手機(jī)這類超級(jí)手機(jī)的興起,現(xiàn)在完全可以繞過運(yùn)營(yíng)商,通過標(biāo)準(zhǔn) TCP/IP 網(wǎng)絡(luò)直接向這些手機(jī)發(fā)送消息,這些消息就稱為推送消息。
推送消息是通過 Apple 和 Google 掌控的互聯(lián)網(wǎng)服務(wù)器發(fā)送的,推送消息從根本上就是設(shè)計(jì)用于與應(yīng)用程序通信的,它們可以發(fā)送文本、多媒體文件和特定于應(yīng)用程序的數(shù)據(jù),例如:警告聲音和顯示在應(yīng)用程序圖標(biāo)上的標(biāo)記等。
推送通知非常適合智能手機(jī)應(yīng)用,但與基于運(yùn)營(yíng)商的移動(dòng)消息傳遞相比,它們的普及性和可靠性都較差。
消息推送的分類和方式等,如下圖:
(1)消息提醒的流程
輸入消息》進(jìn)入消息倉庫》發(fā)送消息》消息流水》消息詳情
(2)消息發(fā)送的時(shí)間
一般為上午 9 點(diǎn)- 10 點(diǎn)
中午 12 點(diǎn)- 14 點(diǎn)
下午 5 點(diǎn)- 6 點(diǎn)
晚上 21 點(diǎn)- 22 點(diǎn)
(3)消息推送的類型
優(yōu)惠券到期通知
客服即時(shí)消息
抽獎(jiǎng)商品到期通知
收藏降價(jià)通知
抽獎(jiǎng)機(jī)會(huì)提醒
訂單發(fā)貨提醒
訂單退貨提醒
購物車商品過期通知
拼團(tuán)到期通知
各大活動(dòng)通知
(4)消息推送的規(guī)則
移動(dòng)端獲得消息通知主要有兩種方式:pull(拉)方式和push(推)方式,下面分別對(duì)這兩種方式做簡(jiǎn)要介紹。
pull方式:
pull方式即“拉方式”,這種方式中手機(jī)上的應(yīng)用程序在啟動(dòng)時(shí)及經(jīng)過一定周期會(huì)定時(shí)連接應(yīng)用的服務(wù)端來獲得服務(wù)器需要傳遞給終端的消息,因?yàn)榇颂幨墙K端從服務(wù)端主動(dòng)獲得消息,因此稱為拉方式。
此方式服務(wù)端實(shí)現(xiàn)簡(jiǎn)單,只需要在終端連接上之后把需要發(fā)送的消息發(fā)送給終端即可,但是此方式有如下弊端:
每個(gè)應(yīng)用終端都需要建立到自己服務(wù)器的socket連接,移動(dòng)終端需要維護(hù)多個(gè)socket連接,較為耗電,不易于治理 。
采納拉的方式,應(yīng)用在啟動(dòng)的時(shí)候會(huì)從應(yīng)用的服務(wù)器上拉取消息;啟動(dòng)之后,應(yīng)用會(huì)周期性的連接服務(wù)器去檢查是否有消息需要拉取,這種方式并不實(shí)時(shí),需要等到終端主動(dòng)拉取的時(shí)候服務(wù)器才能把消息傳遞到終端。如果應(yīng)用頻繁檢查是否有消息需要拉取,那么耗電會(huì)增加,如果檢查周期過長(zhǎng),那么會(huì)影響消息的實(shí)時(shí)性。
綜上,采納pull方式進(jìn)行通知消息的傳遞并不是一個(gè)很好的方法。
push方式:
采納push方式,移動(dòng)終端只需要和推送服務(wù)器之間保持一個(gè)長(zhǎng)連接即可。這樣移動(dòng)終端用于推送的socket連接數(shù)量就與需要推送服務(wù)的應(yīng)用數(shù)量無關(guān)了,只需要維持一個(gè)終端與推送服務(wù)器之間的長(zhǎng)連接即可,所有應(yīng)用的服務(wù)端都是直接連接推送服務(wù)器并通過推送服務(wù)器來把消息推送到終端。而終端也只與推送服務(wù)器進(jìn)行連接即可獲得推送的通知消息。
推送服務(wù)器通過長(zhǎng)連接,在消息到來的時(shí)候可以馬上 把消息推送到連接上來的終端上,實(shí)時(shí)性比較高。
此圖中,推送應(yīng)用1,2, 3 為推送應(yīng)用的服務(wù)端,其負(fù)責(zé)把需要推送的消息放入推送系統(tǒng)。這些應(yīng)用服務(wù)端通過負(fù)載均衡服務(wù)器來連接到具體的推送服務(wù)器。
服務(wù)端是Socket.io的集群,供客戶端(Web、移動(dòng)端)連接。集群后面是一個(gè)Redis服務(wù)器,保存集群中每個(gè)節(jié)點(diǎn)(我們稱之為Cluster)連接的客戶端ID。同時(shí)Redis里面為每一個(gè)Cluster分配了一個(gè)隊(duì)列,保存推送到這個(gè)Cluster的消息。
當(dāng)有消息從某個(gè)客戶端發(fā)出后,所連接的Cluster從Redis里面獵取 這個(gè)消息的目標(biāo)客戶端ID(由于我們同時(shí)支持一對(duì)一私聊和群組,因此一條消息可能會(huì)被推送到多個(gè)客戶端),然后把消息Push到每個(gè)Cluster的消息隊(duì)列里面。
每一個(gè)Cluster都會(huì)以堵塞 方式讀取它所對(duì)應(yīng)的消息隊(duì)列,一旦發(fā)現(xiàn)有消息,就獵取 并且查看其目標(biāo)客戶端ID是不是連接在這個(gè)Cluster上。如果是,就通過Socket.io發(fā)送,如果不是就丟棄。然后繼續(xù)堵塞 讀取,直到下一條消息到達(dá)。
其實(shí)粗略來講,即時(shí)通訊-消息推送只是一種實(shí)現(xiàn),比如:你可以用第三方產(chǎn)品,很輕易的就可以實(shí)現(xiàn)點(diǎn)對(duì)點(diǎn)、甚至點(diǎn)對(duì)多的消息收發(fā)。
但是在用戶需求很個(gè)性化,比如:我要對(duì)用戶的聊天內(nèi)容進(jìn)行監(jiān)控,涉及到敏感的關(guān)鍵字不讓消息推送出去、或者我要對(duì)開通會(huì)員的用戶給予“尊貴的身份”。
相比于免費(fèi)用戶,可以在云端保存時(shí)效更久的聊天記錄或者可以添加的好友數(shù)、群數(shù)更多或者無上限,這時(shí)候?qū)Χㄖ苹囊缶头浅8?,畢竟?shù)據(jù)是寶貴的。這時(shí)候我們就需要自行開發(fā)不能依賴第三方服務(wù)。