一、Apache Apollo服务器其实是一个消息中转站

下载地址 http://activemq.apache.org/apollo/download.html

服务搭建方式,参看博客Android APP必备高级功能,消息推送之MQTT

1、命令行进入解压后bin目录(例:E:>cd E:\MQTT\apache-apollo-1.7.1\bin)。

2、输入apollo create XXX(xxx为创建的服务器实例名称,例:apollo create mybroker),之后会在bin目录下创建名称为XXX的文件夹。

  XXX文件夹下etc\apollo.xml文件下是配置服务器信息的文件。

  etc\users.properties文件包含连接MQTT服务器时用到的用户名和密码,默认为admin=password,即账号为admin,密码为password,可自行更改。

3、进入XXX/bin目录,输入apollo-broker.cmd run开启服务器,看到如下界面代表搭建完成

4、添加Windows服务

进入XXX/bin目录,如下图:

二、Android

AndroidManifest

    <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
        <!-- Mqtt Service -->
<service android:name="org.eclipse.paho.android.service.MqttService" />
<service android:name="com.zyp.mqtt.MQTTService"/>

依赖项

buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.2' // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
} allprojects {
repositories {
jcenter()
mavenCentral()
maven { url "https://repo.eclipse.org/content/repositories/paho-releases/" }
}
}
    compile 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0'
compile 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.0'
compile 'org.greenrobot:eventbus:3.0.0'

Android Service

public class MQTTService  extends Service {

    public static final String TAG = MQTTService.class.getSimpleName();

    private static MqttAndroidClient client;
private MqttConnectOptions conOpt; private String host = "tcp://10.0.2.2:61613";private String userName = "admin";
private String passWord = "password";
private static String myTopic = "topic";
private String clientId = "test"; @Override
public int onStartCommand(Intent intent, int flags, int startId) {
init();
return super.onStartCommand(intent, flags, startId);
} public static void publish(String msg){
String topic = myTopic;
Integer qos = 0;
Boolean retained = false;
try {
client.publish(topic, msg.getBytes(), qos.intValue(), retained.booleanValue());
} catch (MqttException e) {
e.printStackTrace();
}
} private void init() {
// 服务器地址(协议+地址+端口号)
String uri = host;
client = new MqttAndroidClient(this, uri, clientId);
// 设置MQTT监听并且接受消息
client.setCallback(mqttCallback); conOpt = new MqttConnectOptions();
// 清除缓存
conOpt.setCleanSession(true);
// 设置超时时间,单位:秒
conOpt.setConnectionTimeout(10);
// 心跳包发送间隔,单位:秒
conOpt.setKeepAliveInterval(20);
// 用户名
conOpt.setUserName(userName);
// 密码
conOpt.setPassword(passWord.toCharArray()); // last will message
boolean doConnect = true;
String message = "{\"terminal_uid\":\"" + clientId + "\"}";
String topic = myTopic;
Integer qos = 0;
Boolean retained = false;
if ((!message.equals("")) || (!topic.equals(""))) {
// 最后的遗嘱
try {
conOpt.setWill(topic, message.getBytes(), qos.intValue(), retained.booleanValue());
} catch (Exception e) {
Log.i(TAG, "Exception Occured", e);
doConnect = false;
iMqttActionListener.onFailure(null, e);
}
} if (doConnect) {
doClientConnection();
} } @Override
public void onDestroy() {
try {
client.disconnect();
} catch (MqttException e) {
e.printStackTrace();
}
super.onDestroy();
} /** 连接MQTT服务器 */
private void doClientConnection() {
if (!client.isConnected() && isConnectIsNomarl()) {
try {
client.connect(conOpt, null, iMqttActionListener);
} catch (MqttException e) {
e.printStackTrace();
}
} } // MQTT是否连接成功
private IMqttActionListener iMqttActionListener = new IMqttActionListener() { @Override
public void onSuccess(IMqttToken arg0) {
Log.i(TAG, "连接成功 ");
try {
// 订阅myTopic话题
client.subscribe(myTopic,1);
} catch (MqttException e) {
e.printStackTrace();
}
} @Override
public void onFailure(IMqttToken arg0, Throwable arg1) {
arg1.printStackTrace();
// 连接失败,重连
}
}; // MQTT监听并且接受消息
private MqttCallback mqttCallback = new MqttCallback() { @Override
public void messageArrived(String topic, MqttMessage message) throws Exception { String str1 = new String(message.getPayload());
MQTTMessage msg = new MQTTMessage();
msg.setMessage(str1);
EventBus.getDefault().post(msg);
String str2 = topic + ";qos:" + message.getQos() + ";retained:" + message.isRetained();
Log.i(TAG, "messageArrived:" + str1);
Log.i(TAG, str2);
} @Override
public void deliveryComplete(IMqttDeliveryToken arg0) { } @Override
public void connectionLost(Throwable arg0) {
// 失去连接,重连
}
}; /** 判断网络是否连接 */
private boolean isConnectIsNomarl() {
ConnectivityManager connectivityManager = (ConnectivityManager) this.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = connectivityManager.getActiveNetworkInfo();
if (info != null && info.isAvailable()) {
String name = info.getTypeName();
Log.i(TAG, "MQTT当前网络名称:" + name);
return true;
} else {
Log.i(TAG, "MQTT 没有可用网络");
return false;
}
} @Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}

MainActivity 界面方法

public class MainActivity extends AppCompatActivity {

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); EventBus.getDefault().register(this);
startService(new Intent(this, MQTTService.class));
findViewById(R.id.publishBtn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
MQTTService.publish("CSDN 一口仨馍");
}
});
} @Subscribe(threadMode = ThreadMode.MAIN)
public void getMqttMessage(MQTTMessage mqttMessage){
Log.i(MQTTService.TAG,"get message:"+mqttMessage.getMessage());
Toast.makeText(this,mqttMessage.getMessage(),Toast.LENGTH_SHORT).show();
} @Override
protected void onDestroy() {
EventBus.getDefault().unregister(this);
super.onDestroy();
}
}

三、Java服务端

pom文件

    <!-- https://mvnrepository.com/artifact/org.eclipse.paho/org.eclipse.paho.client.mqttv3 -->
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>1.1.0</version>
</dependency>

Server 程序入口

package com.zyp.mqtt;

import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttPersistenceException;
import org.eclipse.paho.client.mqttv3.MqttTopic;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; public class Server { public static final String HOST = "tcp://localhost:61613"; public static final String TOPIC = "topic";
private static final String clientid ="zhaoyazhou_server"; private MqttClient client;
private MqttTopic topic;
private String userName = "admin";
private String passWord = "password"; private MqttMessage message; public Server() throws MqttException {
//MemoryPersistence设置clientid的保存形式,默认为以内存保存
client = new MqttClient(HOST, clientid, new MemoryPersistence());
connect();
} private void connect() {
MqttConnectOptions options = new MqttConnectOptions();
options.setCleanSession(true);
options.setUserName(userName);
options.setPassword(passWord.toCharArray());
// 设置超时时间
options.setConnectionTimeout(10);
// 设置会话心跳时间
options.setKeepAliveInterval(20);
try {
client.setCallback(new PushCallback());
client.connect(options);
topic = client.getTopic(TOPIC);
} catch (Exception e) {
e.printStackTrace();
}
} public void publish(MqttMessage message) throws MqttPersistenceException, MqttException{
MqttDeliveryToken token = topic.publish(message);
token.waitForCompletion();
System.out.println(token.isComplete()+"========");
} public static void main(String[] args) throws MqttException {
Server server = new Server();
server.message = new MqttMessage();
server.message.setQos(1);
server.message.setRetained(true);
server.message.setPayload("Server测试MQTT推送消息".getBytes());
server.publish(server.message);
System.out.println(server.message.isRetained()+"------ratained状态");
} }

回调函数 PushCallback

package com.zyp.mqtt;

import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttMessage; public class PushCallback implements MqttCallback { @Override
public void connectionLost(Throwable arg0) {
// 连接丢失后,一般在这里面进行重连
System.out.println("连接断开,可以做重连"); } @Override
public void deliveryComplete(IMqttDeliveryToken token) {
// publish后会执行到这里
System.out.println("deliveryComplete---------"+ token.isComplete()); } @Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
// subscribe后得到的消息会执行到这里面
System.out.println("订阅的字符串:"+topic);
System.out.println("消息内容:"+message.toString()); }
}

四、调试

启动Apollo服务

将Android App启动,链接上服务器,如图:

启动服务端程序,发送信息,如图:

手机端接收到信息,如图:

参考博客:Android APP必备高级功能,消息推送之MQTT

参考博客:MQTT JAVA发送、订阅、收集消息

参考博客:MQTT协议之 Apache Apollo服务

参考文章:MQTT Part 4 发布,订阅和退订

参考文章:MQTT基础入门第四部分:MQTT 发布,订阅以及退订

Android Apollo MQTT入门的更多相关文章

  1. 学Android开发,入门语言java知识点

    学Android开发,入门语言java知识点 Android是一种以Linux为基础的开源码操作系统,主要使用于便携设备,而linux是用c语言和少量汇编语言写成的,如果你想研究Android,就去学 ...

  2. Android Studio单元测试入门

    Android Studio单元测试入门 通常在开发Android app的时候经常会写一些小函数并验证它是否运行正确,通常做法我们是把这个函数放到某个界面(Activity上)执行一下,运行整个工程 ...

  3. 下面就介绍下Android NDK的入门学习过程(转)

    为何要用到NDK? 概括来说主要分为以下几种情况: 1. 代码的保护,由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大. 2. 在NDK中调用第三方C/C++库,因为大部分的开源库 ...

  4. Android渗透测试Android渗透测试入门教程大学霸

    Android渗透测试Android渗透测试入门教程大学霸 第1章  Android渗透测试 Android是一种基于Linux的自由及开放源代码的操作系统,主要用于移动设备,如智能手机.平板等.目前 ...

  5. 一看就懂的Android APP开发入门教程

    一看就懂的Android APP开发入门教程 作者: 字体:[增加 减小] 类型:转载   这篇文章主要介绍了Android APP开发入门教程,从SDK下载.开发环境搭建.代码编写.APP打包等步骤 ...

  6. (转)Android: NDK编程入门笔记

    转自: http://www.cnblogs.com/hibraincol/archive/2011/05/30/2063847.html 为何要用到NDK? 概括来说主要分为以下几种情况: 1. 代 ...

  7. Android Wear 开发入门

    大家好,我是陆嘉杰,我是一名Android开发者.我想和大家进行一些技术交流,希望越来越多的人能和我成为好朋友. 大家都知道,智能手表是下一个开发的风口,而这方面的技术又属于前沿,所以和大家分享下An ...

  8. Android 学习资料入门到精通(PDF集合)共54本

    最近收集一些安卓入门到精通,包含游戏编程,网络编程,多媒体开发,需要学习朋友就下载保持下来,下载链接在最下面 下面是网盘内容 14天学会安卓开发_(完整版).pdf Android 4  游戏高级编程 ...

  9. android 开发从入门到精通

    Android-Tips This is an awesome list of tips for android. If you are a beginner, this list will be t ...

随机推荐

  1. 【项目管理】 使用IntelliJ IDEA 将项目发布(提交)到GitLab

    https://blog.csdn.net/zsq520520/article/details/51004721 gitlab地址: http://192.168.1.81:200   idea项目p ...

  2. [TJOI2015]概率论[卡特兰数]

    题意 \(n\) 个节点二叉树的叶子节点的期望个数. \(n\leq 10^9\) . 分析 实际询问可以转化为 \(n\) 个点的不同形态的二叉树的叶子节点总数. 定义 \(f_n\) 表示 \(n ...

  3. CentOS7.4 部署 Django + Python3 + Apache + Mod_wsgi

    安装环境 Remote: CentOS 7.4 x64 (django.example.com) Python: Python3.6.5 Apache: Apache 2.4.6 Mod_wsgi: ...

  4. angularjs中audio/video 路径赋值问题

    之前解决这个问题都是通过js的attr赋值解决的,但是也一直不明白为什么audio直接在HTML中赋值报错.解决方法就是通过添加$sce过滤效果 app.filter("trustUrl&q ...

  5. CentOS搭建Docker Hub私有仓库

    docker pull registry拉取registry镜像 docker images查看镜像 docker run -d -p 5000:5000 -v /opt/data/registry: ...

  6. mysql批量新增或者更新

    1.批量更新或者新增 1.单个新增或者更新 keyProperty新增完之后返回Id值

  7. leetcode-填充同一层的兄弟节点Ⅱ

    给定一个二叉树 struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *next; } 填充它的每个 ...

  8. Docker--删除容器实例和镜像

    一.删除容器实例 使用命令docker rm 容器ID或者容器名 1.docker ps -a查询已有的实例 [root@cxt data]# docker ps -a 2.docker rm 容器I ...

  9. CentOS查看一共安装了多少软件包,是那些软件包

    转载请注明出处:http://blog.csdn.net/l1028386804/article/details/48292853 一.如何得知共安装了多少个软件包 [root@localhost ~ ...

  10. 【Docker】第五篇 Docker 数据管理

    一.基本介绍 数据管理的原因:Docker中的容器一旦删除,容器本身的rootfs文件系统就会被删除,容器中的所有数据就会被删除.为了对一些需要持久化的数据,不随容器删除而删除,所以我们可以通过多个容 ...