曹鵬飛,李 杰,楊 君
(三江學(xué)院 計(jì)算機(jī)科學(xué)與工程學(xué)院,江蘇 南京 210012)
隨著移動互聯(lián)網(wǎng)技術(shù)的發(fā)展,各類消息縱橫交錯,人們在獲取關(guān)聯(lián)信息時常感到無從選擇。傳統(tǒng)的消息獲取,用戶需要主動拉取網(wǎng)絡(luò)存儲的消息,此種方式獲取消息的效率極其低下,會產(chǎn)生眾多與用戶無關(guān)的消息。消息推送需要用戶不停的拉取刷新,屬于被動推送[1]。隨著云技術(shù)的發(fā)展,消息推送技術(shù)逐步轉(zhuǎn)變?yōu)樵仆扑停鎰e了單一服務(wù)器推送的模式。
1999年,網(wǎng)景公司推出了基于XML的簡易信息聚合(RSS)[2];2005年,聯(lián)合格式(Atom)發(fā)布[3],可以看作是RSS2.0的改進(jìn)方案。
2009年,Google提出了PubSubHubbub[4],將消息獲取由“拉取”模式轉(zhuǎn)變?yōu)椤巴扑汀蹦J剑蛻舳瞬辉俣〞r輪詢服務(wù)器,當(dāng)有更新時及時推送至客戶端,成為了互聯(lián)網(wǎng)分散式消息傳播的開放標(biāo)準(zhǔn),提供了消息即時更新。
2011年,H5標(biāo)準(zhǔn)將WebSocket協(xié)議納入Web交互,在瀏覽器客戶端與服務(wù)器之間通過TCP/IP技術(shù)實(shí)現(xiàn)了無刷新的通信[5]。
隨著云計(jì)算和移動互聯(lián)網(wǎng)的發(fā)展,消息推送技術(shù)也逐漸成熟,蘋果公司推出了APNS(Apple Push Notification Service)[6],安卓系統(tǒng)(Android)從2.2版本開始增加了云消息推送模塊(C2DM)現(xiàn)更名為(Google Cloud Message,GCM)[7],微軟在WinPhone系統(tǒng)提供了云消息推送服務(wù)(Microsoft Push Notification Service,MPNS)[8]。
現(xiàn)有的消息推送大多屬于主題式訂閱模式,隨著Web開發(fā)技術(shù)的發(fā)展, WebSocket作為一種新的技術(shù)被應(yīng)用在消息推送中,有廣闊的應(yīng)用前景,但是針對不同平臺終端的推送應(yīng)用還未有統(tǒng)一標(biāo)準(zhǔn)。
消息推送服務(wù)通過云服務(wù)器構(gòu)建消息主體向移動端進(jìn)行推送,包括:消息推送平臺、云服務(wù)器、移動客戶端(Android)。通過實(shí)時消息處理模塊將消息發(fā)送到移動客戶端,客戶端接收到消息內(nèi)容。主要需求如下:
(1)消息推送平臺。
提供消息服務(wù)接口:采用Restful API[9]架構(gòu)實(shí)現(xiàn)即時通信消息推送API接口,通過JSON進(jìn)行格式化編碼;
消息推送功能:調(diào)用API接口將消息發(fā)送給中間組件,再將消息推送至移動終端;
日志監(jiān)測功能:將系統(tǒng)運(yùn)行過程產(chǎn)生的錯誤記錄并保存,監(jiān)測系統(tǒng)運(yùn)行狀態(tài)。
(2)云服務(wù)器。
架設(shè)在公有云:讓用戶通過公網(wǎng)IP地址直接訪問;
存儲服務(wù):提供數(shù)據(jù)的存儲和消息的緩存;
云服務(wù)器進(jìn)行相關(guān)配置,以實(shí)現(xiàn)消息服務(wù)的部署。
(3)移動客戶端(Android)。
用戶管理:提供給管理員用戶管理的功能,同時對用戶進(jìn)行權(quán)限分配。如:添加、修改、刪除用戶等,返回操作狀態(tài);
業(yè)務(wù)處理模塊:手機(jī)終端進(jìn)行標(biāo)記,通過算法生成標(biāo)識符(Token),讓手機(jī)接收消息時具有唯一標(biāo)識。手機(jī)服務(wù)喚醒,一旦檢測到消息推送,調(diào)用接口程序進(jìn)行喚醒,提示用戶查看消息。實(shí)時消息推送,調(diào)用消息推送平臺提供API接口實(shí)時推送消息給用戶。
1.2.1 總體框架設(shè)計(jì)
系統(tǒng)總體框架由客戶端、業(yè)務(wù)處理、消息推送服務(wù)和數(shù)據(jù)庫系統(tǒng)四個模塊構(gòu)成,如圖1所示。

圖1 實(shí)時消息推送服務(wù)框架
圖1中顯示了系統(tǒng)中四個模塊之間的關(guān)系,其中:
(1)客戶端模塊包括消息展示,采用顯示展示的方式,并伴隨著手機(jī)振動和手機(jī)鈴聲;服務(wù)喚醒,調(diào)用安卓手機(jī)系統(tǒng)服務(wù)進(jìn)行喚醒。
(2)業(yè)務(wù)處理模塊包括身份認(rèn)證、用戶管理、推送業(yè)務(wù)等。身份認(rèn)證,對所有用戶進(jìn)行分組管理授予不同的權(quán)限,區(qū)分用戶等級;用戶信息管理,對用戶數(shù)據(jù)進(jìn)行增刪改查;推送業(yè)務(wù),調(diào)用消息推送服務(wù)API接口,將消息主題和內(nèi)容傳遞給消息推送服務(wù)模塊。
(3)消息推送服務(wù)模塊包括推送接口、推送服務(wù)。推送接口,通過構(gòu)造HTTP(get、post)請求,將信息發(fā)送給推送服務(wù),返回給業(yè)務(wù)處理模塊;推送服務(wù),構(gòu)建消息傳輸隊(duì)列,建立TCP長連接,消息推送至移動終端。
1.2.2 數(shù)據(jù)庫系統(tǒng)設(shè)計(jì)
數(shù)據(jù)庫存儲包括用戶賬戶、用戶權(quán)限、手機(jī)注冊等數(shù)據(jù)。數(shù)據(jù)庫各表之間關(guān)系如圖2所示。

圖2 數(shù)據(jù)關(guān)系
如表1所示,User表存儲所有用戶的賬戶數(shù)據(jù),包括:姓名、密碼、郵箱、最后IP、最后登錄時間等數(shù)據(jù),各表之間通過Role_id、User_role、User_id進(jìn)行關(guān)聯(lián)。

表1 User表結(jié)構(gòu)
Avos表,存儲用戶手機(jī)信息,與User表外鍵User_id進(jìn)行關(guān)聯(lián)。User_id存儲用戶編號;Key存儲手機(jī)序列號,Phone_Name存儲手機(jī)名稱,Create_T和Update_T是用戶創(chuàng)建和更新的時間。
Role表,存儲用戶角色,Id為主鍵整型自增。Res_id是資源編號。Group_N是分組名稱,Res_T是資源類型,與Group_N互為唯一索引。Create_T和Update_T是用戶創(chuàng)建和更新的時間,不能為空。
實(shí)時消息推送服務(wù)主要由3個模塊協(xié)作運(yùn)行,包括:管理模塊、消息推送服務(wù)模塊和客戶端模塊。
管理模塊通過框架Rails來實(shí)現(xiàn),消息推送服務(wù)模塊通過框架Gin實(shí)現(xiàn),客戶端模塊采用安卓移動終端,通過Gin框架中WebSocket組件構(gòu)造URL請求,客戶端中請求URL地址獲取消息的推送。
管理模塊由用戶權(quán)限管理、用戶信息管理、APP信息、實(shí)時推送四個部分構(gòu)成。管理模塊實(shí)現(xiàn)框架如圖3所示,通過Ruby on Rails框架[10]來實(shí)現(xiàn)。
其中Model模型層處理業(yè)務(wù)流程,Controller控制器中有3個控制器,分別為:PUSH、App_down和User,分別控制推送功能、客戶端下載功能、User資源的操作。View視圖層主要是圖形頁面展示。
用戶權(quán)限管理,賦予不同用戶不同分組,再將分組賦予不同權(quán)限。用戶創(chuàng)建時通過Usermodel中的Add_role事務(wù)將用戶與用戶角色表(Role)關(guān)聯(lián)。

圖3 實(shí)現(xiàn)框架
用戶信息管理對用戶賬戶信息進(jìn)行添、刪、改、查等操作,通過JS代碼對用戶注冊信息進(jìn)行初步驗(yàn)證,再提交表單與服務(wù)器進(jìn)行校驗(yàn)。
實(shí)時推送功能模塊使用HTTP/1.1協(xié)議,采用POST方法將信息傳遞給消息推送服務(wù)。使用RstClient.post構(gòu)造Http_Post請求,對數(shù)據(jù)進(jìn)行格式化處理運(yùn)用JSON輸出。如請求失敗則通過Error獲取錯誤的原因,調(diào)用Deliver方法將郵件發(fā)送給管理員。
前端頁面選擇響應(yīng)式瀏覽方式,讓用戶可以在多種終端中自動切換,JS通過Rails框架提供的方法將回調(diào)信息展示在頁面上。
消息推送服務(wù)使用Golang中Gin框架,由協(xié)議層、路由分發(fā)中間層、數(shù)據(jù)模型層和業(yè)務(wù)處理層組成,消息推送服務(wù)模塊結(jié)構(gòu)如圖4所示。

圖4 消息推送服務(wù)模塊結(jié)構(gòu)
系統(tǒng)底層是HTTP協(xié)議,通過Gin框架Router方法路由分發(fā)中間層處理,將原本默認(rèn)端口改為自定義2333避免端口被占用情況。在數(shù)據(jù)模型層中構(gòu)建數(shù)據(jù)模型訪問Avos和User表中地數(shù)據(jù)。業(yè)務(wù)處理層通過推送接口進(jìn)行實(shí)現(xiàn)。具體實(shí)現(xiàn)過程如下:
先建立TCP長連接,服務(wù)器通過連接通道推送消息。傳統(tǒng)的Socket連接[11]資源消耗較多,采用心跳機(jī)制MQTT協(xié)議[12]可以降低消耗來維持較長時間的連接。
移動端需要不斷地輪詢Publish端[14]。當(dāng)有新消息客戶端就能監(jiān)聽和獲取到消息。消息推送服務(wù)實(shí)現(xiàn)過程如圖5所示。

圖5 消息推送服務(wù)實(shí)現(xiàn)過程
先構(gòu)建Struct:Umeng,使用InitUmeng方法初始化結(jié)構(gòu)體Umeng指針,通過函數(shù)指針從ClientNotify獲取PostData數(shù)據(jù),發(fā)送給消息推送功能API接口。
客戶端選擇安卓(Android)系統(tǒng)作為消息接收端,客戶端在后臺需要一直監(jiān)聽Switch事件,用戶在移動端開啟推送服務(wù)后,系統(tǒng)先對消息服務(wù)進(jìn)行注冊,然后調(diào)用SwichPus方法與手機(jī)序列號進(jìn)行綁定,序列號生成則調(diào)用PushAgent類中GetRegistrationId()方法實(shí)現(xiàn),最后將序列號發(fā)送到安卓客戶端的消息隊(duì)列中。
消息展示采用顯式的形式,控制消息類將消息推送到移動終端,UmengNotificationClickHandler構(gòu)造LaunchApp方法來監(jiān)聽消息推送事件,通過SetNotificationPlaySound()調(diào)用手機(jī)系統(tǒng)鈴聲,并通過NotifiCationService類的onCreate方法喚醒系統(tǒng)進(jìn)程。
3.1.1 云實(shí)驗(yàn)環(huán)境相關(guān)配置
消息推送服務(wù)部署在云實(shí)驗(yàn)環(huán)境下。選用阿里云服務(wù)器,通過阿里云直接分配的公網(wǎng)IP地址:139.40.62.77。使用Nginx為代理服務(wù)器[13],將unicorn服務(wù)使用8282端口映射,腳本配置如下:
Upstream Back {
Server 139.40.62.77:8282;//云服務(wù)器IP和端口號}
server{
listen80;//Web服務(wù)轉(zhuǎn)發(fā)端口
Root /var/www/push_web;//服務(wù)主目錄
Location{
proxy_pass http://Back;//地址轉(zhuǎn)發(fā)
proxy_set_header X-Real-IP $remote_ip_addr;//代理IP頭部設(shè)置
proxy_redirect_off;//重定向url關(guān)閉
proxy_set_header X-Forwarded-For $remote_ip_addr;
}
}
(1)實(shí)驗(yàn)云服務(wù)器軟硬件環(huán)境。
服務(wù)器軟硬件配置:阿里云ECS服務(wù)器,CPU:2.8G/16核;內(nèi)存:8 G;帶寬:100 Mbps;操作系統(tǒng):Centos7 64位;應(yīng)用服務(wù):Nginx 1.10.3、MySQL 5.6。
(2)客戶端環(huán)境。
手機(jī)型號:三星S7;安卓版本:Android 6.0;運(yùn)行內(nèi)存:4 G;存儲內(nèi)存:32 GB。
3.1.2 系統(tǒng)運(yùn)行
云端系統(tǒng)搭建完成后,在手機(jī)上安裝消息推送服務(wù)APP。服務(wù)端發(fā)送測試消息,客戶端能夠收到,系統(tǒng)運(yùn)行如圖6所示。

圖6 系統(tǒng)運(yùn)行
3.2.1 測試指標(biāo)
系統(tǒng)測試包括功能測試和性能壓力測試。
功能測試主要運(yùn)用黑盒測試[15-16],通過編寫系統(tǒng)各功能的測試用例進(jìn)行測試,驗(yàn)證結(jié)果的正確性,包括消息推送功能和用戶權(quán)限測試。
性能壓力測試通過自定義腳本來模擬大規(guī)模的消息,測試消息推送的到達(dá)率。
3.2.2 主要功能測試
消息推送功能測試用例,用戶權(quán)限測試用例,如表2所示。

表2 主要功能測試用例
3.2.3 性能壓力測試
本測試針對系統(tǒng)進(jìn)行壓力測試,計(jì)算系統(tǒng)消息推送的到達(dá)率,具體測試用例如表3所示。

表3 消息推送到達(dá)率測試用例
測試用例腳本如下:
For (i=0;i<1000;i++){
RstC.post 'http://139.40.62.77:81/push_phone',{'msg'-> i.to_s,'User_id' -> 2,'titl'-> "msg:#{i.to_s}" }
}//獲取系統(tǒng)Post接口
根據(jù)測試數(shù)據(jù)看出,系統(tǒng)整體性能良好,每千次消息推送中到達(dá)率為96.8%,在網(wǎng)絡(luò)狀態(tài)良好的情況下延遲較低,平均響應(yīng)時間為33.9 ms,能正常運(yùn)行。
提出了在云實(shí)驗(yàn)環(huán)境下實(shí)現(xiàn)實(shí)時消息推送服務(wù)的構(gòu)建方案,對消息推送服務(wù)框架進(jìn)行了設(shè)計(jì),運(yùn)用WebSocket技術(shù)實(shí)現(xiàn)了管理平臺和移動客戶端應(yīng)用程序,并將其部署在阿里云實(shí)驗(yàn)環(huán)境中。經(jīng)過測試,在良好的網(wǎng)絡(luò)環(huán)境下消息能夠?qū)崟r、準(zhǔn)確地推送至移動端。