推送原理解析 極光推送使用詳解


推送原理解析 極光推送使用詳解

12016.09.22 18:10:07字數 5,705閱讀 19,494

推送技術產生場景:

--服務器端主動性: 客戶端與服務器交互都是客戶端主動的, 服務器一般不能主動與客戶端進行數據交互, 因為服務器端無法得知客戶端的 IP 地址 及 狀態;

--數據實時性: 如果服務器端有緊急數據要傳遞給客戶端, 就必須主動向客戶端發送數據;

--基本原理: 使客戶端實時獲取服務器端消息, Pull 方式, 小周期輪詢, 費電費流量; 另一個就是 Push 方式, 服務器端向客戶端主動推送數據, 可以省電省流量;

一. 推送原理

1. Android 推送原理簡介

(1) SMS 方式推送

SMS 推送:

--SMS: Short Message Service 縮寫, 即短信服務;

--實現方式: 服務器端向手機端發送短信, 手機監聽短信廣播, 然后將攔截的短信信息進行顯示;

--優點: 省電, 省流量, 在沒有網絡的偏遠地點也能接收到推送消息;

--缺點: 費錢, 一毛錢一條;

(2) 輪詢 方式推送

輪詢推送:

--實現方式: 周期性主動獲取網絡中的數據;

--缺點: 費電, 費流量;

(3) 長鏈接 方式推送

長鏈接推送: 主流方法;

--實現方式: 手機端與服務器端建立一條長時間的數據流鏈接, 手機客戶端一直等待服務器端的數據;

--優點: 有一條長鏈接, 有數據的時候才發送數據, 沒有時不消耗流量, 比較省流量;

--缺點: 由於要保存一條長鏈接, 比較費電; 在網絡不穩定的情況下, 推送容易失敗;

2. Android 推送解決方案簡介

(1) C2DM 推送 (Google)

C2DM 推送簡介: 全稱 Cloudto Device Messaging, Google 提供的 推送解決方案;

--運行方式: 提供一個輕量級機制, 允許服務器通知應用程序, 主動與客戶端進行數據交互, 處理消息排隊, 並向運行於目標設備的應用程序分發消息;

--優點: Google 提供的原生框架, 無需在應用中添加第三方代碼 和 部署服務器端;

--缺點: 1.該推送依賴 Google 服務器, 需要綁定 Google 帳號, 目前在中國 Google 被屏蔽, 無法使用; 2. 許多手機廠商去掉了軟件中的該模塊;

--運行機制圖:

(2) MQTT 推送 (IBM)

MQTT 推送簡介: MQTT 是輕量級的消息發布"訂閱協議,

--優點: 省電, 省流量, 輕量級, 有 C++ 版的服務器端組件 RSMB;

--缺點: RSMB 不開源, 部署成本高, 比較復雜;

--IBM相關MQTT官網: http://www-01.ibm.com/support/docview.wss?rs=171&uid=swg24006006 ;

RSMB 服務器端: 全稱 Really Small Message Broker, IBM 提供;

--工作方式: 在服務器端, 接收消息, 並將 消息 傳輸給指定移動設備;

--地址: http://www.alphaworks.ibm.com/tech/rsmb ;

MQTT 推送示例:

--客戶端: https://github.com/tokudu/AndroidPushNotificationsDemo ;

--服務器端 PHP: https://github.com/tokudu/PhpMQTTClient ;

(3) 基於 XMPP 的 AndroidPN 推送 (開源)

XMPP 推送簡介:

--XMPP 簡介: 全稱 Extensible Messaging and Presence Protocol (可擴展通訊和表示協議), 基於可擴展標記語言(XML)的協議,它用於即時消息(IM)以及在線探測, 該協議允許因特網用戶向因特網上的其他任何人發送即時消息;

--AndroidPN: 基於 XMPP 協議開發的 Java 開源 Android 推送通知實現, 包含了完整的客戶端 和 服務器端;

--項目主頁: http://sourceforge.net/projects/androidpn/ ;

--原理圖:

AndroidPN 缺陷: 如果使用該框架進行推送, 需要在了解 XMPP 和 anroidPN 基礎上進行大量的二次開發;

--連接中斷: 連接時間過長, 連接會中斷, 收不到消息;

--穩定性差: 該框架不是很穩定;

--糾錯機制: 消息推送出去后, 不檢查是否推送到客戶端, 推送出去就不管了;

3. 推送 4s 評價標准

4S 標准:Safe(安全),Stable(穩定),Save(省電省流量省成本),Slim(體積小);

(1) Safe (安全)

推送安全標准:

--透明傳輸: 只負責點對點的傳輸的質量, 不關心中間的傳輸介質 與 傳輸業務邏輯 協議等;

--加密方案: 信息需要加密, 另外推送的 ID 系統需要獨立與后台已有的 ID 系統;

(2) Stable (穩定)

服務器穩定: 長鏈接方案對服務器開銷要求很高, 服務器端開發難度很大;

--在線峰值: 同時在線連接數到達100萬的穩定性;

--並發時延: 高並發時的消息平均延遲, 一分鍾處理 100萬 條數據;

--服務器穩定: 穩定性時延占總時間的 99.9%, 有備份和負載均衡的機制;

客戶端穩定: 中國網絡狀況復雜, 手機長時間聯網比較難, 穩定性比較難, 開發時要考慮每個省的每個運營商, 每款手機的機型;

--聯網時間: 每日聯網時間 23.5 小時以上;

--消息到達率: 消息收到后 9 小時內客戶端的消息到達率;

(3) Save (節省)

節省評判:

--電量節省: 注意 CPU 休眠率, 服務短待機時間百分比評判;

--流量節省: 處理協議 和 冗余數據包, 使用空載待機月流量評判;

--成本節省: 單服務器同時承載連接數, 同時承載連接數越多, 成本越低, 個推單服務器連接 300 萬(業內頂尖水平);

(4) Slim (體積小)

集成 SDK 大小: 客戶端推送的 SDK 的大小盡量小, 一般要小於 300K;

二. 極光推送概述

1. 功能概述

極光推送基本功能:主動即時的向用戶發起交互, 可以發送聊天消息;

--作用: 通過向精准的目標用戶推送有價值的消息, 可以提供用戶忠誠度, 提高留存率;

(1) 推送方式

推送方式簡介:

--通知: 推送文本內容, 展示在通知欄中;

--自定義消息: 推送自定義消息, 給用戶自行處理;

--富媒體: 推送 HTML 頁面內容;

(2) 推送目標

推送目標簡介:

--廣播推送: 向所有用戶發送廣播消息;

--標簽推送: 根據用戶設置的標簽分組, 向某一組推送消息;

--別名推送: 客戶端綁定用戶別名, 向單個用戶推送信息;

(3) 用戶分群

用戶分群簡介: 可以根據 JPush 提供的多條件組合, 對用戶進行群組划分, 實現實時篩選推送;

(4) 推送歷史

推送歷史簡介: 通過 WEB 或者 API 發出的推送, 都可以在推送歷史記錄中查詢到, 並可以實時顯示推送結果;

2. 推送框架

推送框架:

--推送數據源: 自己開發的服務器端 或者 使用 極光推送官網的 WEB 后台;

--JPush API: 部署在服務器端, 開發者的服務器端發起推送時, 將數據傳到 JPush API 中, 然后再向下傳遞;

--建立長鏈接: 集成 JPush 的 SDK 客戶端啟動后會建立一個到 JPush Cloud 的長鏈接, 提供 App 永遠在線的能力;

--原理圖:

3. 極光推送原理

參考文章(極光推送官方博客): http://blog.jpush.cn/jpush_wireless_push_principle/ ;

(1) 客戶端原理

IP地址 分配原理:

--IP 地址有限: IPv4 的 IP 地址數量有限, 運營商要動態地為 手機分配 IP 地址, 這些 IP 地址都是運營商的內網 IP;

--網絡地址轉換 (NAT): 全稱 Network Address Translation, 網關維護一個外網 IP 地址, 與 內網 IP 地址對應;

--外網 IP 不固定: 由於運營商持有的外網 IP 數量有限, 需要動態的分配給接入運營商的用戶, 因此在手機一段時間沒有數據傳輸時會將該手機分配的外網 IP 地址收回, 分配給其它用戶;

--解決方案: Android 手機端想要保持長鏈接, 首先外網 IP 地址不能變, 不能讓運營商收回 這個 IP 地址;

Android 手機端實現方案:

--心跳: 為了長時間保持外網 IP, 需要客戶端定期發送心跳給運營商, 以便刷新 NAT 列表;

--Timer 定時方法: 該類計划循環執行定時任務, 但是使用該類會使 CPU 保持喚醒狀態, 比較費電;

--AlarmManager 定時方法: 該類封裝了 Android 手機的 RTC 硬件時鍾模塊, 可以在 CPU 休眠時正常運行, 定時任務執行時再喚醒 CPU, 這樣做到了電量節省;

(2) 服務器原理

C10K 問題: 單台服務器解決 同時保持一萬長鏈接的性能問題;

4. Android SDK 簡介

Android SDK 本質: JPush SDK 集成到 Android APP 中后,作為一個 Service 在 Android 端長期運行, 始終與 服務器端 保持者長鏈接, 相當與永遠在線;

(1) 多平台支持

多平台支持:

--手機芯片類型: 一般的手機是 ARM 芯片, 但是有些手機是 MIPS 芯片 或者 x86 芯片;

--so 庫支持: 每個 CPU 芯片類型對應的 so 庫, 都需要特殊編譯, 無法跨平台調用, 如 ARM 平台的 so 庫在 x86 平台就無法運行;

(2) 電量與流量說明

流量消耗: JPush 的協議是自定義的, 協議的數據量經過了精簡, 流量消耗非常少;

電量消耗: JPush 心跳保持連接時可以在 CPU 不喚醒的情況下執行, 減少了不必要的代碼運行, 電量非常節省;

(3) 相關庫說明

JPush 依賴庫:

--.so 依賴庫內容: JPush 需要一個 so 動態庫, 該庫是 C 語言編寫, 在 Linux 下進行交叉編譯而來, 可以在 ARM 芯片的手機上運行;

--jar 依賴庫內容: 對 Java 代碼的封裝;

三. 極光推送簡單 Demo

Demo 概述: JPush 官方提供了一個簡單 Demo, 向我們演示了 JPush 基本的推送流程, 基本步驟分為下面幾塊, 即

--Web 配置操作部分: 包括 注冊開發者帳號, 創建應用;

--下載手機示例: 下載系統自動生成的 Android 應用示例;

--發送推送指令: 在 Web 端發送推送指令, 手機端接收該指令;

--官方地址: 關於該模塊詳細信息可參考官方文檔, http://docs.jpush.io/guideline/android_3m/ ;

1. Web 配置操作

(1) 帳號創建

該步驟就不再贅述, 普通的帳號注冊即可;

(2) 創建應用

創建應用步驟:

--創建應用界面: https://www.jpush.cn/common/apps ;

--創建應用: 點擊 創建應用 按鈕即可;

--配置應用信息: 輸入應用名稱, 上傳一個圖標, 然后填寫一個包名, JPush 系統會在后台根據你輸入的包名生成的推送的 Android 應用 Demo, 該 Demo 包含了該配置的信息;

查看應用設置界面:

2. 下載導入 Android 應用源碼

(1) 下載 Android 應用源碼

下載源碼: 在應用設置的 Android 模塊, 有 "下載 Android Example" 按鈕, 點擊該按鈕即可下載 Android 應用;

(2) 導入 Android 應用源碼

將下載后的源碼解壓, 不用任何修改, 即可導入到應用中運行;

3. 發送推送

(1) 不初始化推送無效

直接在后台推送: 我們在 Android 手機界面不做任何操作, 直接在網頁后台推送消息;

--發送通知: 在應用的 "推送" 模塊, 點擊發送通知按鈕;

--輸入推送內容: 輸入任意推送內容 "Jpush Demo Send By octopus 1.", 點擊頁面最下方的 "立即發送" 按鈕;

--對話框選擇: Web 界面會彈出對話框, 提示是否發送, 選 "發送吧" 即可;

--查看推送結果: 點擊之后又彈出對話框, 點擊 "去看看" 可以查看推送結果;

--推送結果分析: 點擊上面的 "去看看" 可以查看推送結果, 點擊 "推送歷史" 按鈕, 也可一查看推送結果; 由於我們沒有在 客戶端進行初始化, 因此推送沒有成功;

(2) 初始化后推送

初始化之后推送:

--手機端初始化: 點擊手機端的 "initPush" 按鈕, 進行初始化;

--發送消息: 發送 "Jpush Demo Send By octopus 2." 消息, 此時連上一次推送的消息也送達, 網絡不同會延遲一定時間;

--查看發送結果: 此時顯示的推送, 兩次都成功了;

(3) 停止 和 恢復 推送功能

停止恢復推送功能: 當點擊停止推送 "stopPush" 按鈕時, 推送手機端就不會再接收推送內容, 當點擊恢復推送時, 會將期間積攢的所有推送內容一次性推送到手機中;

四. Android 應用集成 JPush

1. 依賴庫拷貝

(1) SDK 簡介

SDK 下載: 最新的 SDK 壓縮包 Jpush-Android-sdk-1.7.3.zip ;

--JPush SDK 下載頁面: http://docs.jpush.io/resources/ ;

--Android SDK 下載地址: https://www.jpush.cn/downloads/sdk/android/ ;

詳細文件說明: 將 Jpush-Android-sdk-1.7.3.zip 解壓, 解壓后的目錄是 Jpush-Android-sdk;

--查看文檔目錄: 使用 tree -L 3 命令, 查看深度為 3 的路徑結構;

octopus@octopus:~/JPush/Jpush-Android-sdk$ tree -L 3

.

├── AndroidManifest.xml

├── ChangeLog.txt

├── doc

│  └── Jpush-sdk-集成指南.pdf

├── example

│  ├── AndroidManifest.xml

│  ├── libs

│  │  ├── armeabi

│  │  ├── armeabi-v7a

│  │  └── jpush-sdk-release1.7.3.jar

│  ├── proguard-project.txt

│  ├── project.properties

│  ├── res

│  │  ├── drawable-hdpi

│  │  ├── drawable-ldpi

│  │  ├── drawable-mdpi

│  │  ├── drawable-xhdpi

│  │  ├── layout

│  │  ├── values

│  │  └── values-zh

│  └── src

│      └── com

└── libs

├── armeabi

│  └── libjpush173.so

├── armeabi-v7a

│  └── libjpush173.so

└── jpush-sdk-release1.7.3.jar

--AndroidManifest.xml (配置文件): 這是 Android 應用的主要配置文件示例;

--ChangeLog.txt (升級說明): SDK 版本升級的說明;

--doc (文檔): doc 目錄下 有個 "Jpush-sdk-集成指南.pdf" 文檔, 這是集成 JPush 文檔;

--example (代碼示例): example 明顯是個 Android 示例 demo;

--libs (依賴庫): Android 應用中相關庫, 放在這個目錄中, libjpush173.so 是依賴的 C 底層庫, jpush-sdk-release1.7.3.jar 是依賴的 Java 庫;

(2) 拷貝 依賴庫 到 Android 應用中

執行過程:

--創建應用: 創建一個空應用, 注意應用最小版本應大於 2.1, 否則不能支持極光推送, 應用的包名為 cn.org.octopus.jpush.demo 即可, 不用在后台另外創建一個

--拷貝依賴庫: 在工程根目錄下創建一個 libs 目錄, 拷貝jpush-sdk-release1.7.3.jar到 libs 目錄中, 將armeabi/libjpush173.so和armeabi-v7a/libjpush173.so拷貝到 libs 目錄, 注意要連文件夾一起拷貝, 拷貝完后如下圖;

2. 配置 AndroidManifest.xml 文件

(1) 權限配置

JPush 定義權限: JPush 定義了一個權限, 允許應用接收 JPush 代碼發送的廣播消息, You Package.permission.JPUSH_MESSAGE, 注意要使用你的包名替換其中的 Your Package;

 

用戶權限:

 

可選用戶權限 :

 

(2) 配置 JPush 服務

JPush 服務:

--推送服務:

 

android:name="cn.jpush.android.service.PushService"

android:enabled="true"

android:exported="false" >

--下載服務:

 

android:name="cn.jpush.android.service.DownloadService"

android:enabled="true"

android:exported="false" >

(3) 配置 JPush 廣播接收者

JPush 廣播接收者配置:

--推送接收者:

 

android:name="cn.jpush.android.service.PushReceiver"

android:enabled="true" >

 

 

 

 

-- 時鍾相關接收者 :

 

(4) 配置 渠道 和 推送標識

渠道 和 AppKey 配置:

 

 

 

 

 

 

 

(5) 最終的配置文件

配置好的文件:

 

package="cn.org.octopus.jpush.demo"

android:versionCode="1"

android:versionName="1.0" >

android:minSdkVersion="17"

android:targetSdkVersion="19" />

android:allowBackup="true"

android:icon="@drawable/ic_launcher"

android:label="@string/app_name"

android:theme="@style/AppTheme">

android:name=".MainActivity"

android:label="@string/app_name" >

android:name="cn.jpush.android.service.PushService"

android:enabled="true"

android:exported="false" >

android:name="cn.jpush.android.service.DownloadService"

android:enabled="true"

android:exported="false" >

android:name="cn.jpush.android.service.PushReceiver"

android:enabled="true" >

3. 推送測試

后台推送:

--控制台地址: https://www.jpush.cn/common/apps/ ;

--發起推送: 進入控制台, 點擊對應的應用, 進入推送頁面;

--查看結果:

--推送統計:

五. JPush 相關 API

1. 初始化 停止 恢復 推送

推送控制方法:

--初始化推送: JPushInterface.init(Context context), 初始化之后才能接收推送消息;

--恢復推送: JPushInterface.resumePush(Context context), 停止推送后, 調用該方法, 即可恢復推送;

--停止推送: JPushInterface.stopPush(Context context), 調用該方法之后, 手機便收不到推送信息了;

代碼示例 :

public void onClick(View view) {

int id = view.getId();

switch (id) {

case R.id.init_jpush:

//初始化 JPush, 初始化之后才可以進行推送, 否則推送失敗

JPushInterface.init(this);

//設置調試模式, 可以在 LogCat 中查看 JPush 日志

JPushInterface.setDebugMode(true);

break;

case R.id.start_jpush:

//恢復推送

JPushInterface.resumePush(getApplicationContext());

break;

case R.id.stop_jpush:

//停止推送

JPushInterface.stopPush(getApplicationContext());

break;

default:

break;

}

}

界面效果及說明:

--界面效果:

--按鈕說明: 點擊 "初始化" 按鈕就可以接收推送消息, 點擊 "停止推送" 按鈕手機停止接收消息推送, 點擊 "恢復推送" 即開始接收推送消息;

2. 根據 別名 和 標簽 分組推送

參考文檔: http://docs.jpush.cn/pages/viewpage.action?pageId=557241

(1) 概念介紹

別名:

--作用: 別名用於代表安裝了應用的用戶, 每個用戶對應着一個別名;

--用戶與別名對應性 (多對一): 每個用戶只能指定一個別名, 一個別名可以同時指定給多個用戶, 給別名發消息時, 會同時給所有設置該別名的用戶發消息;

標簽:

--作用: 方便開發者根據標簽發送推送消息;

--用戶與標簽對應性(多對多): 一個用戶可以有多個標簽, 一個標簽可以設置給多個用戶;

(2) 設置別名標簽接口方法

設置別名與標簽方法:

--方法接口:

public static void setAliasAndTags(

Context context, //上下文對象

String alias, //別名, 只能設置一個別名

Set tags, //標簽集合, 可設置多個標簽

TagAliasCallback callback) //回調接口, 其中有一個 gotResult 接口方法, 系統回傳入錯誤碼給 responseCode 參數

-- 別名設置說明 : a. 設置 null(沒有地址) 即不設值值; b. 設置 "" (初始化后) 即清空之前的設置; c. 設置會覆蓋之前的設置; d. 長度 40字節 UTF8 編碼;

--標簽設置說明:a. 設置 null(沒有地址) 即不設值值; b. 設置 空集合(沒有數據, 已經初始化) 即清空之前的設置; c. 設置會覆蓋之前的設置; d. 每個標簽長度 40字節 UTF8 編碼, 最多 100 個標簽;

設置別名方法:

--方法接口:

public static void setAlias(

Context context, //上下文對象

String alias, //別名內容

TagAliasCallback callback) //回調接口

-- 參數說明 : 該參數與 setAliasAndTags 方法參數相同;

設置標簽方法:

--方法接口:

public static void setTags(

Context context,

Set tags,

TagAliasCallback callback)

--參數說明:該參數與setAliasAndTags 方法參數相同;

過濾無效標簽: 感覺這純屬 JPush API 定義缺陷, 這個應該對我們隱藏才對;

--方法接口:

public static Set filterValidTags(Set tags)

--作用: 設置標簽時如果 標簽Set集合 中有一個是無效的, 那么整個設置都無效, 應該是設計缺陷, 后期修補 BUG 的權益之際;

回調接口: TagAliasCallback 回調接口;

--方法接口:

public void gotResult(

int responseCode, //錯誤碼

String alias, //別名

Set tags); //標簽集合

代碼示例:

--設置方法代碼:

String alias = set_alias.getText().toString();

String tag = set_tag.getText().toString();

Set set = new HashSet();

set.add(tag);

JPushInterface.setAliasAndTags(

getApplicationContext(),

alias,

set,

this);

Log.i(TAG, "已設置別名 與 標簽");

-- 回調方法 :

@Override

public void gotResult(int arg0, String arg1, Set arg2) {

Log.i(TAG, "錯誤碼 : " + arg0 + " , 別名 : " + arg1);

}

--手機端設置:

-- 后台發送極光推送 :

--設置標簽:

--標簽報錯: 如果設置的標簽沒有手機注冊, 會出現如下報錯;

--推送結果:

--推送通知消息:

3. 根據 RegistrationID 進行單機推送

參考文檔 : http://docs.jpush.cn/pages/viewpage.action?pageId=8814639

(1) 概念介紹

RegistrationID 簡介: 應用第一次注冊到 JPush 后台時, 會生成一個唯一的設備標識 RegistrationID, 每個設備不重復;

(2) 獲取RegistrationID

方法接口:

//SDK 初次注冊成功后,開發者通過在自定義的 Receiver 里監聽 Action - cn.jpush.android.intent.REGISTRATION 來獲取對應的 RegistrationID。注冊成功后,也可以通過此函數獲取

public static String getRegistrationID(Context context)

-- 獲取 RegistrationID 代碼 :

//獲取 RegistrationID

String registrationid = JPushInterface.getRegistrationID(getApplicationContext());

tv_registrationid.setText("RegistrationID : " + registrationid);

--界面示例:

--后台推送設置:

4. 清除通知

清除通知簡介 :

-- 方法接口 :

public static void clearAllNotifications(Context context);

-- 代碼示例 :

case R.id.clear_notification:

//清除所有通知

JPushInterface.clearAllNotifications(getApplicationContext());

break;

-- 效果 : 在后台發送一條消息, 點擊清除按鈕, 所有的推送通知都清除;

5. 推送時間限制

(1) 設置允許推送時間

方法接口:

public static void setPushTime(

Context context, //上下文對象

Set weekDays, //允許接收推送的 一周天數

int startHour, //開始時間

int endHour) //結束時間

-- 代碼示例 :

Set days = new HashSet();

days.add(1);

days.add(2);

days.add(3);

days.add(4);

days.add(5);

JPushInterface.setPushTime(getApplicationContext(), days, 10, 23);

(2) 設置禁止推送時間

方法接口:

public static void setSilenceTime(

Context context, //上下文對象

int startHour, //開始時間-小時

int startMinute, //開始時間-分鍾

int endHour, //結束時間-小時

int endMinute) //結束時間-分鍾

-- 代碼示例 :

JPushInterface.setSilenceTime(getApplicationContext(), 22, 30, 8, 30);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM