MQTT+ActiveMQ实现消息推送(移动端)

这个小程序是我导师给我布置的一个任务,网上教程不是很多,遇到的一些困难都是自己解决的,所以写出来分享一下,有什么问题大家可以留言,尽力帮大家解决。

首先,我们需要先下载activeMQ
(官网:http://activemq.apache.org/download.html)

来到解压目录下,进入bin目录下的win64文件夹(如何是32位机器则进入win32),运行activemq.bat。如果出现拒绝访问则右键以管理员身份运行,出现下图时说明activemq启动成功。
MQTT+ActiveMQ实现消息推送(移动端)_第1张图片

移动端的下载地址 https://github.com/nymar123/MqttPusher

服务器启动成功后,即可打开移动端点击对应按钮进行连接。

如何出现MqttException的异常,就是连接服务器失败, 请检查服务器是否打开以及URL和端口是否正确

连接成功后,移动端就可以接收activeMQ消息服务器上传过来的消息,效果图如下
MQTT+ActiveMQ实现消息推送(移动端)_第2张图片

我用的是org.eclipse.paho.client.mqttv3,里面封装了MqttClient、MqttConnection、MqttTopic、MqttMessage等类,附带下service的代码,带有比较详细的注解,可以看下各种类的作用,有需要的可以去查下源码

public class MQTTService extends Service {
    //消息服务器的URL
    public static final String BROKER_URL = "tcp://192.168.191.6:1883";
    //客户端ID,用来标识一个客户,可以根据不同的策略来生成
    public static final String clientId = "android-client";
    //订阅的主题名
    public static final String TOPIC = "test";
    //mqtt客户端类
    private MqttClient mqttClient;
    //mqtt连接配置类
    private MqttConnectOptions options;  

    private String userName = "admin";
    private String passWord = "password";


    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onStart(Intent intent, int startId) {

        try {
            //在服务开始时new一个mqttClient实例,客户端ID为clientId,第三个参数说明是持久化客户端,如果是null则是非持久化
            mqttClient = new MqttClient(BROKER_URL, clientId, new MemoryPersistence());

            // MQTT的连接设置  
            options = new MqttConnectOptions();  
            // 设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录,这里设置为true表示每次连接到服务器都以新的身份连接 
            //换而言之,设置为false时可以客户端可以接受离线消息
            options.setCleanSession(false);  
            // 设置连接的用户名  
            options.setUserName(userName);  
            // 设置连接的密码  
            options.setPassword(passWord.toCharArray());  
            // 设置超时时间 单位为秒  
            options.setConnectionTimeout(10);  
            // 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线,但这个方法并没有重连的机制  
            options.setKeepAliveInterval(20);  
            // 设置回调  回调类的说明看后面
            mqttClient.setCallback(new PushCallback(this));  
            MqttTopic topic = mqttClient.getTopic(TOPIC);  
            //setWill方法,如果项目中需要知道客户端是否掉线可以调用该方法。设置最终端口的通知消息    
            options.setWill(topic, "close".getBytes(), 2, true); 
            //mqtt客户端连接服务器
            mqttClient.connect(options);

            //mqtt客户端订阅主题
            //在mqtt中用QoS来标识服务质量
            //QoS=0时,报文最多发送一次,有可能丢失
            //QoS=1时,报文至少发送一次,有可能重复
            //QoS=2时,报文只发送一次,并且确保消息只到达一次。
            int[] Qos  = {1};  
            String[] topic1 = {TOPIC};  
            mqttClient.subscribe(topic1, Qos); 


        } catch (MqttException e) {
            Toast.makeText(getApplicationContext(), "Something went wrong!" + e.getMessage(), Toast.LENGTH_LONG).show();
            e.printStackTrace();
        }

        super.onStart(intent, startId);
    }

    @Override
    public void onDestroy() {
        try {
            mqttClient.disconnect(0);
        } catch (MqttException e) {
            Toast.makeText(getApplicationContext(), "Something went wrong!" + e.getMessage(), Toast.LENGTH_LONG).show();
            e.printStackTrace();
        }
    }
}
public class PushCallback implements MqttCallback {
//回调方法类需要实现MqttPushBack接口,用于消息推送过程中某一事件触发后进行相应的处理
    private ContextWrapper context;

    public PushCallback(ContextWrapper context) {

        this.context = context;
    }

    @Override
    public void connectionLost(Throwable cause) {
        //连接断开时的回调方法,可以在这里重新连接
    }

    @SuppressLint("NewApi")
    @Override
    public void messageArrived(MqttTopic topic, MqttMessage message) throws Exception {
        //有新消息到达时的回调方法
        final NotificationManager notificationManager = (NotificationManager)
                context.getSystemService(Context.NOTIFICATION_SERVICE);

        final Notification notification; 


        final Intent intent = new Intent(context, BlackIceActivity.class);
        final PendingIntent activity = PendingIntent.getActivity(context, 0, intent, 0);

        Notification.Builder builder = new Notification.Builder(context)  
                .setAutoCancel(true)  
                .setContentTitle("Message")  
                .setContentText(new String(message.getPayload()) + " ")  
                .setContentIntent(activity)  
                .setSmallIcon(R.drawable.snow)  
                .setWhen(System.currentTimeMillis())  
                .setOngoing(true);  
        notification=builder.getNotification();
        notification.flags |= Notification.FLAG_AUTO_CANCEL;
        notification.number += 1;
        notificationManager.notify(0, notification);
    }

    @Override
    public void deliveryComplete(MqttDeliveryToken token) {
        //成功发布某一消息后的回调方法
    }
}

这里顺带介绍下activeMQ的web console,通过它我们可以很快捷轻松地来发布推送的内容。

用浏览器打开127.0.0.1:8161/admin(具体URL取决于部署IP),登陆的用户名密码默认均为admin
MQTT+ActiveMQ实现消息推送(移动端)_第3张图片

我们可以看到当前服务器中存在的topic,在subscribers页面下我们还可以看到订阅者的列表

那么如何发布消息呢?在topic页面下点击某一topic
MQTT+ActiveMQ实现消息推送(移动端)_第4张图片

这里有很多属性可以根据自己的需要进行设置,点击send就可以对该topic的订阅用户进行推送了

你可能感兴趣的:(消息推送,activemq,mqtt,消息推送)