APP消息推送(APP Push)解決方案-服務(wù)端工作邏輯和實現(xiàn)

一堕担、APP 推送概述:

App推送消息是我們常見的一種app消息提醒方式。

我們的實現(xiàn)需要第三方的支持,實現(xiàn)方式是后臺通過接口將Push請求發(fā)送至第三方讽营,第三方實現(xiàn)在App所在設(shè)備上的推送。

二泡徙、APP推送后臺處理邏輯:

在與推送平臺交互時橱鹏,后臺需要向第三方發(fā)送兩部分信息,推送目標(biāo)終端標(biāo)示+推送內(nèi)容

1堪藐、推送目標(biāo)終端標(biāo)示:

APP推送需要定位目標(biāo)終端莉兰,也就是說要給那臺設(shè)備進行推送,

簡單的情況下礁竞,單設(shè)備推送糖荒,我們需要拿到一個終端ID的概念,用于定位目標(biāo)設(shè)備模捂,

注:不同渠道中使用的單設(shè)備ID方式也不盡相同寂嘉,以下用TokenID來表示這個終端ID的概念。

而實際推送渠道中往往還有自定義的功能枫绅,比如通過打標(biāo)簽的方式將TokenID進行劃分泉孩,達到批量差異化的效果。

2并淋、推送內(nèi)容:

即指通過API接口參數(shù)的定義終端上收到的Push消息的內(nèi)容和格式寓搬。

其中IOS的推送消息在展示上區(qū)別于安卓的一點是沒有title,title的部分只能是默認的APP名稱县耽,而安卓的部分雖然默認值也是APP名稱句喷,但是也支持自定義title。

三兔毙、后端實現(xiàn):

通過上述的處理邏輯可得知唾琼,后端首先需要登記客戶端的TokenId,然后保持TokenID的有效性更新澎剥,然后在需要發(fā)送APP推送時拿到用戶的有效TokenID锡溯,

然后使用TokenID和已有的內(nèi)容信息通過API與三方Push服務(wù)交互,完成推送哑姚。

即后端的實現(xiàn)分為兩部分:

1祭饭、TokenID的登記

2、App Push API的調(diào)用

注:以下示例中有兩個元素為本項目的特殊情況:

其中product_id是因為當(dāng)前項目中客戶端同時有多個版本叙量,不同版本需要推送獨立處理倡蝙,但在同一張表內(nèi)統(tǒng)一記登記;

而login_id跟member_id同時存在是因為當(dāng)前系統(tǒng)中存在共享賬戶的情況绞佩,一般賬號賬戶一對一的情況login_id和member_id是綁定的寺鸥,不需要同時重復(fù)登記猪钮。

1、TokenID的登記:
  • 以下是現(xiàn)項目使用的TokenID登記表結(jié)構(gòu):

<pre>
/==============================================================/

/* Table: sys_app_push_token */

/==============================================================/

create table sys_app_push_token

(

record_id int(11) not null auto_increment,

login_id int(11),

member_id int(11),

push_token varchar(200),

visit_device int(4) comment '3:Android;4:IOS',

product_id varchar(20) default '0' comment '',

push_channel int(4) default 1 comment '1:IOS信鴿,2:華為,3:小米,4:極光',

nstatus int(4) not null default 0 comment '狀態(tài):0:申請中胆建;1:生效躬贡;2:失效;3:刪除眼坏;4:歷史記錄',

create_userid int(11) not null default 0,

create_time varchar(20) character set utf8 not null default "",

edit_userid int(11) not null default 0,

edit_time varchar(20) character set utf8 not null default "",

this_remark text,

description text,

create_ordernum varchar(30) character set utf8 comment '記錄創(chuàng)建時的流水號',

last_ordernum varchar(30) character set utf8 comment '記錄最后一次編輯時的流水號',

primary key (record_id)

)

ENGINE=InnoDB

DEFAULT CHARACTERSET=utf8

COLLATE=utf8_general_ci

auto_increment=10000

row_format=COMPACT;

alter table sys_app_push_token comment 'app推送token表';

/==============================================================/

/* Index: Index_1 */

/==============================================================/

create index Index_1 on sys_app_push_token

(

record_id

);
</pre>

  • 以下是APP上傳TokenID接口上傳參數(shù)列表:
image.png

注:其中拂玻,推送渠道絕對在做Push時使用哪家API,參數(shù)的判定交由客戶端進行處理宰译,后端直接登記判定結(jié)果檐蚜。

  • 以下是TokenID登記接口處理方法

<pre>
@Transactional(readOnly=false)

publicbooleanuploadMemberPushTokenEnt(TrainVansContext trainVansContext) {

try{

//check already data

trainVansContext.getTrainVansRequest().put("login_id", TrainVansUtils.getMV(trainVansContext.getTrainVansRequest(),"login_login_id"));

// get All memberRelation

trainVansContext.getTrainVansRequest().put("relation_type", TrainVansUtils.getMV(trainVansContext.getTrainVansRequest(),"visit_role"));

List> memberRelationList = SpringContextHandler.getBean(MemberService.class).getRelateMemberListByLoginId(trainVansContext);

for(Map memberRelateMap : memberRelationList){

//

trainVansContext.getTrainVansRequest().put("member_id", TrainVansUtils.getMV(memberRelateMap,"member_id"));

Map tokenMap = SpringContextHandler.getBean(AppPushService.class).getPushTokenMapByLoginMap(trainVansContext.getTrainVansRequest());

//disable already data

if(tokenMap !=null){

if(!TrainVansUtils.getMV(tokenMap,"push_token").equals(TrainVansUtils.getMV(trainVansContext.getTrainVansRequest(),"push_token"))){

//

trainVansContext.getTrainVansRequest().put("record_id", TrainVansUtils.getMV(tokenMap,"record_id"));

if(!SpringContextHandler.getBean(AppPushService.class).updateDiabledThePushToken(trainVansContext)){

thrownewRuntimeException("TranVans_Operate_Exception");

}

//insert new data

if(!SpringContextHandler.getBean(AppPushService.class).insertPushTokenRecord(trainVansContext)){

thrownewRuntimeException("TranVans_Operate_Exception");

}

}

}else{

//insert new data

if(!SpringContextHandler.getBean(AppPushService.class).insertPushTokenRecord(trainVansContext)){

thrownewRuntimeException("TranVans_Operate_Exception");

}

}

}

returntrue;

}catch(Exception e) {

TrainVansUtils.setRetInfo(trainVansContext,"10005001","Register TokenID Error");

e.printStackTrace();

thrownewRuntimeException("TranVans_Operate_Exception");

}

}
</pre>
注:方法外部有一個關(guān)于對應(yīng)本賬號的對賬戶列表的遍歷,遍歷中的處理部分為TokenID的登記處理操作沿侈。

2闯第、APP Push API 的調(diào)用

推送渠道:

APP推送不僅僅要求在APP打開狀態(tài)時或者后臺運行時進行消息推送,更多的場景是在移動終端關(guān)閉APP的場景下進行消息推送缀拭,

渠道的優(yōu)劣無非在于兩個維度咳短,送達率和送達效率。

其中安卓推送的渠道較為雜亂蛛淋,其中華為和小米提供的PUSH服務(wù)對于自平臺的移動終端支持的較為完善咙好,而沒有廠商提供PUSH服務(wù)的終端只能通過

第三方服務(wù)來進行對接。

對于現(xiàn)有的這些渠道進行如下總結(jié):

1褐荷、IOS:信鴿推送勾效,這個推送在我門公司中經(jīng)歷了三個項目,推送效果穩(wěn)定叛甫。API接入也方便层宫,是IOS端的不二選擇。

2其监、Android-華為:華為自平臺萌腿。

3、Android-小米:小米自平臺抖苦。

4毁菱、Android-其他:目前使用的是“極光推送”。在理想狀態(tài)下送達率和送達效率表現(xiàn)很好睛约,但并不如以上三家渠道穩(wěn)定鼎俘。

在進行調(diào)用時可根據(jù)之前定義的push_channel分發(fā)給各自的渠道哲身,各渠道的具體對接請各自查看官網(wǎng)辩涝,API都很完善。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末勘天,一起剝皮案震驚了整個濱河市怔揩,隨后出現(xiàn)的幾起案子捉邢,更是在濱河造成了極大的恐慌,老刑警劉巖商膊,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件伏伐,死亡現(xiàn)場離奇詭異,居然都是意外死亡晕拆,警方通過查閱死者的電腦和手機藐翎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來实幕,“玉大人吝镣,你說我怎么就攤上這事±ケ樱” “怎么了末贾?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長整吆。 經(jīng)常有香客問我拱撵,道長,這世上最難降的妖魔是什么表蝙? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任拴测,我火速辦了婚禮,結(jié)果婚禮上府蛇,老公的妹妹穿的比我還像新娘昼扛。我一直安慰自己,他們只是感情好欲诺,可當(dāng)我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布抄谐。 她就那樣靜靜地躺著,像睡著了一般扰法。 火紅的嫁衣襯著肌膚如雪蛹含。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天塞颁,我揣著相機與錄音浦箱,去河邊找鬼。 笑死祠锣,一個胖子當(dāng)著我的面吹牛酷窥,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播伴网,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼蓬推,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了澡腾?” 一聲冷哼從身側(cè)響起沸伏,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤糕珊,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后毅糟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體红选,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年姆另,在試婚紗的時候發(fā)現(xiàn)自己被綠了喇肋。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡迹辐,死狀恐怖苟蹈,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情右核,我是刑警寧澤慧脱,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站贺喝,受9級特大地震影響菱鸥,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜躏鱼,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一氮采、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧染苛,春花似錦鹊漠、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至畔师,卻和暖如春娶靡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背看锉。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工姿锭, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人伯铣。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓呻此,卻偏偏與公主長得像,于是被迫代替她去往敵國和親腔寡。 傳聞我的和親對象是個殘疾皇子焚鲜,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,691評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 極光推送: 1.JPush當(dāng)前版本是1.8.2,其SDK的開發(fā)除了正常的功能完善和擴展外也緊隨蘋果官方的步伐,SD...
    Isspace閱讀 6,724評論 10 16
  • 58同城高性能移動PUSH推送平臺架構(gòu)演進之路 58同城作為中國最大的生活服務(wù)平臺恃泪,涵蓋了房產(chǎn)郑兴、招聘犀斋、二手贝乎、二手車...
    meng_philip123閱讀 3,126評論 3 38
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,312評論 25 707
  • 冥想是瑜伽實現(xiàn)入定的一項技法和途徑,把心叽粹、意览效、靈完全專注在原始之初中,讓人專注于超感官的世界虫几,能使人能全身心的投入...
    石榴小紀閱讀 481評論 0 2
  • 1 嗡噠咧嘟噠咧嘟咧梭哈 2 獨自一人時師父總會不停的寫著一句話锤灿,后來那句話便成了我的劫。 3 前來求符者大都十...
    林風(fēng)起閱讀 176評論 0 3