構建私有化APP系統消息推送(不依賴任何雲服務)

首先介紹本文目標,很多時候我們開發APP都看到微信或QQ那樣的APP在鎖屏的情況都都會出來消息提示功能,此功能的確能為APP提高用戶體驗和消息傳達到機主的實時性和有效性。

系統架構:

1.MQTT Broker使用Coolpy7高性能MQTT服務端,相關測試數據請關注我查看之前發表的文章。

2.安卓端MQTT客戶端,接收消息後使用local push功能把消息推顯到系統

3.MQTTLens一個基於谷歌瀏覽器的MQTT客戶端工具,通過此工具發送消息到安卓越端

開始構建系統

1.運行Coolpy7核心服務

Coolpy7核心服務是一個最原始最單純功能完備的MQTT消息服務器端,包括功能有:QoS:0,QoS1,QoS2消息質量支持。Will消息支持等等。深入瞭解 https://mcxiaoke.gitbooks.io/mqtt-cn/content/

  1. 防止暴力連接攻擊,對已連接客戶端進行優先保護
  2. 防止空連接攻擊,當用戶連接建立後兩秒鐘內沒有進行身份驗證即主動關閉客戶端連接

通過ssh進入服務器192.168.200.201,並確保你已經按照 https://coolpy7.gitbook.io/coolpy7book/kai-shi-shi-yong/start 配置服務器操作系統的網絡優化配置。

Coolpy7核心服務運行後會自行構當前目錄下的data文件夾,此文件夾存放MQTT運行期所需求持久化的數據信息,使用的是開源項目 https://github.com/jacoblai/yiyidb,支持10億級秒op的高性能數據庫,數據庫內核使用的是Leveldb技術。

# 下載服務器端
git clone https://github.com/Coolpy7/Coolpy7.git && cd Coolpy7
# 解壓文件
unzip go_build_Coolpy7_go_linux.zip
# 提權
chmod -R 777 go_build_Coolpy7_go_linux
# 啟動Coolpy7 啟動參數
# l 當前服務Host地址 (默認為:1883即本地1883端口,此參數一般默認即可,無需配置)
# a 連接接入調度器最大線程,此值可防止暴力連接攻擊,對已連接客戶端進行優先保護 (默認值128)
./go_build_Coolpy7_go_linux
# 啟動成功後會打印如下信息,即說明服務端已正常啟動,host於1883端口,請確保相關防火牆配置可用
2018/10/29 12:59:55 Coolpy7 tcp is listening on [::]:1883

一般需為程序提權才可以運行Linux服務,指令:chmod -R 777 go_build_Coolpy7_go_linux

2.安卓端MQTT客戶端及消息推送顯示功能

需要用到開源庫 paho,更多paho的接收可以查看paho官網:http://www.eclipse.org/paho/files/android-javadoc/index.html

引入依賴庫:

在APP下Gradle中添加:

dependencies {
compile 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'
compile 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.1'
}


在project下Gradle中添加:

repositories {
maven {
url "https://repo.eclipse.org/content/repositories/paho-releases/"
}
}

添加權限

<uses-permission>
<uses-permission>
<uses-permission>
<uses-permission>
<uses-permission>
<uses-permission>

開啟服務,在AndroidMainFest.xml中開啟MQTT服務:


<service>

訂閱器的實現

a.首先創建MqttAndroidClient和MqttConnectOptions, Coolpy7默認端口是1883, 以下代碼中的ip換成最終你運行Coolpy7所在機器的內網ip地址即可

MqttAndroidClient mqttAndroidClient = new MqttAndroidClient(getApplicationContext(), "192.168.1.56:1883", clientId);
MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();

b.設置MqttConnectOptions屬性

mqttConnectOptions.setAutomaticReconnect(true);
mqttConnectOptions.setCleanSession(false);
mqttConnectOptions.setUserName(null);
mqttConnectOptions.setPassword(null);
mqttConnectOptions.setConnectionTimeout(30); //超時時間

mqttConnectOptions.setKeepAliveInterval(60); //心跳時間,單位秒
mqttConnectOptions.setAutomaticReconnect(true);//自動重連
構建私有化APP系統消息推送(不依賴任何雲服務)

c.創建MQTT連接和設置監聽

mqttAndroidClient.connect(mqttConnectOptions);
mqttAndroidClient.setCallback(new MqttCallbackExtended() {
@Override
public void connectComplete(boolean reconnect, String serverURI) {
Log.e(TAG, "reconnect ---> " + reconnect + " serverURI--->" + serverURI);
}
@Override
public void connectionLost(Throwable cause) {
Log.e(TAG, "cause ---> " + cause);
}
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
Log.e(TAG, "topic ---> " + topic + " message--->" + message);
startNotification(message);
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
Log.e(TAG, "token ---> " + token);
}
});

d.訂閱消息,在connectComplete方法訂閱消息

final String subscriptionTopic = "exampleAndroidTopic";
\tprivate void subscribeToTopic() {
try {
mqttAndroidClient.subscribe(subscriptionTopic, 0, null, new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
Log.e(TAG, "onFailure ---> " + asyncActionToken);
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
Log.e(TAG, "onFailure ---> " + exception);
}
});
} catch (MqttException e) {
Log.e(TAG, "subscribeToTopic is error");
e.printStackTrace();
}
}

3.實現Notification

private NotificationManager notificationManager ;
private NotificationCompat.Builder notificationBuilder ;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initNotification();
\t}
\t
\tprivate void initNotification() {
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationBuilder = new NotificationCompat.Builder(this);
}

初始化完成後在監聽器messageArrived方法中接收消息

@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
Log.e(TAG, "topic ---> " + topic + " message--->" + message);
startNotification(message);
}

private void startNotification(MqttMessage message) {
// params
Bitmap largeIcon = ((BitmapDrawable) getResources().getDrawable(R.mipmap.ic_launcher_round)).getBitmap();
String info = message.toString();
Intent intent = new Intent(MainActivity.this,JumpActivity.class);
intent.putExtra(MESSAGE,info);
notificationBuilder.setLargeIcon(largeIcon)
.setSmallIcon(R.mipmap.ic_launcher_round)
.setContentTitle("推送消息啦")
.setContentText(info)
.setTicker(info)
.setContentIntent(PendingIntent.getActivity(MainActivity.this, 0, intent, 0));
Notification notification = notificationBuilder.getNotification();
notificationManager.notify(NOTIFICATION_ID, notification);
}

效果展示

構建私有化APP系統消息推送(不依賴任何雲服務)

請關注本賬號,會持續為您提供更多商業級應用示例

Coolpy7開源地址:https://github.com/Coolpy7

Coolpy7技術手冊:https://coolpy7.gitbook.io/coolpy7book/


分享到:


相關文章: