优秀的编程知识分享平台

网站首页 > 技术文章 正文

构建私有化APP系统消息推送(不依赖任何云服务)

nanyue 2024-09-12 15:51:21 技术文章 8 ℃

首先介绍本文目标,很多时候我们开发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 android:name="android.permission.WAKE_LOCK" />
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
 <uses-permission android:name="android.permission.READ_PHONE_STATE" />
 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
 <uses-permission android:name="android.permission.INTERNET" />

开启服务,在AndroidMainFest.xml中开启MQTT服务:

<!-- Mqtt Service -->
 <service android:name="org.eclipse.paho.android.service.MqttService" />

订阅器的实现

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);//自动重连

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";
	private 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();
	}
	
	private 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);
 }

效果展示

请关注本账号,会持续为您提供更多商业级应用示例

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

Coolpy7技术手册:https://coolpy7.gitbook.io/coolpy7book/

最近发表
标签列表