Android中MQTT的使用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wanliguodu/article/details/82703229

最近在做关于Android端从ActiveMQ中取数据的应用。如果ActiveMQ中有数据,就往Android端推送。

1.ActiveMQ和MQTT

  ActiveMQ 是 Apache 出品,最流行的,强有力的开源消息总线。MQ英文名MessageQueue,中文名也就是大家用的消息队列,说白了就是一个消息的接受和转发的容器,可用于消息推送。ActiveMQ 是一个完全支持 JMS1.1 和 J2EE 1.4 规范的 JMS Provider实现,尽管JMS 规范出台已经很久的事情了,但是 JMS 在当今的J2EE 应用中间仍然扮演着特殊的地位。支持Java,C,C ++,C#,Ruby,Perl,Python,PHP等各种跨语言客户端和协议。MQTT v3.1对ActiveMQ也是支持的。
  那什么是MQTT?MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议,有可能成为物联网的重要组成部分。该协议支持所有平台,几乎可以把所有联网物品和外部连接起来,被用来当做传感器和制动器(比如通过Twitter让房屋联网)的通信协议。Mqtt各个平台下用到的包还有例子。接下来我主要介绍的是Android平台的MQTT的使用。

2.fusesource和paho

  看了网上的许多介绍,大多数都用的是这个两个基于MQTT协议实现的jar。fusesourcepaho这两个项目我最开始用的是fusesource,因为网上好多都说这个简单易用而paho用起来复杂一些。但是,我用之后发现我跳入了fusesource的大坑里。我当时用的Android 4.4的系统,内存时1G(没办法,客户就提供这个系统)。虽然客观条件艰苦,但也没有必要运行项目一段时间后就报OOM的错。当时数据量(图片的URL)还是挺大的,1秒大概可以推送20条数据的量。错误大概是这个样的:

java.lang.OutOfMemoryError
    at org.fusesource.hawtdispatch.util.BufferPool.create(BufferPool.java:35)
    at org.fusesource.hawtdispatch.util.BufferPool.create(BufferPool.java:25)
    at org.fusesource.hawtdispatch.util.ThreadLocalPool.checkout(ThreadLocalPool.java:78)
    at org.fusesource.hawtdispatch.transport.AbstractProtocolCodec.allocateNextWriteBuffer(AbstractProtocolCodec.java:153)
    at org.fusesource.hawtdispatch.transport.AbstractProtocolCodec.flushNextWriteBuffer(AbstractProtocolCodec.java:186)
    at org.fusesource.hawtdispatch.transport.AbstractProtocolCodec.flush(AbstractProtocolCodec.java:229)
    at org.fusesource.hawtdispatch.transport.TcpTransport.flush(TcpTransport.java:678)
    at org.fusesource.hawtdispatch.transport.TcpTransport$5.run(TcpTransport.java:579)
    at org.fusesource.hawtdispatch.internal.HawtCustomDispatchSource$1.run(HawtCustomDispatchSource.java:127)
    at org.fusesource.hawtdispatch.internal.SerialDispatchQueue.run(SerialDispatchQueue.java:100)
    at org.fusesource.hawtdispatch.internal.pool.SimpleThread.run(SimpleThread.java:77)

我开始一直以为是我自己写的代码问题而导致的这个问题,我是千方百计的优化,费尽心力的google,最终也是无济于事。好吧,我放弃了,小伙伴们要是知道这个问题怎么解决,给我留下言啊。然后我就投入到paho的怀抱中了。接下来,让我们瞅一瞅怎么入门吧!

3.paho的配置

3.1 build.gradle

    compile 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0'
    compile 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'

3.2 AndroidManifest.xml

权限:

     <!-- 使用paho必须要使用的3个权限,sPermissions the Application Requires -->
    <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.INTERNET" />

service:

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

3.3 Activity

    String serverUri = "tcp://***.***.**.***:1883";
    MqttAndroidClient mqttAndroidClient;
    String clientId = "pahoAndroidClient";
    //订阅的主题
    String [] topics = new String[]{"ActiveMQ/Metadata","ActiveMQ/Mdblk"};

public void initMQTT(){

        clientId = clientId + System.currentTimeMillis();

        mqttAndroidClient = new MqttAndroidClient(getApplicationContext(),serverUri,clientId);
        mqttAndroidClient.setCallback(new MqttCallbackExtended() {
            @Override
            public void connectComplete(boolean reconnect, String serverURI) {
                Log.i("paho","connectComplete reconnect:"+reconnect);
                Log.i("paho","connectComplete serverURI:"+serverURI);
                if (reconnect) {
                    // Because Clean Session is true, we need to re-subscribe
                    subscribeToTopic();
                } else {
                    Log.i("paho","connectComplete 没有重新连接");
                }
                Toast.makeText(MainActivity.this,"connectComplete",Toast.LENGTH_SHORT).show();

            }

            @Override
            public void connectionLost(Throwable cause) {
                Log.i("paho","The Connection was lost.:"+cause);

            }

            @Override
            public void messageArrived(String topic, MqttMessage message) throws Exception {

                System.out.println("Incoming message: " + topic + " : " + new String(message.getPayload()));

            }

            @Override
            public void deliveryComplete(IMqttDeliveryToken token) {

            }
        });

        MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
        mqttConnectOptions.setAutomaticReconnect(true);
        mqttConnectOptions.setCleanSession(false);
        try {
            mqttAndroidClient.connect(mqttConnectOptions, null, new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {
                    DisconnectedBufferOptions disconnectedBufferOptions = new DisconnectedBufferOptions();
                    disconnectedBufferOptions.setBufferEnabled(true);
                    disconnectedBufferOptions.setBufferSize(100);
                    disconnectedBufferOptions.setPersistBuffer(false);
                    disconnectedBufferOptions.setDeleteOldestMessages(false);
                    mqttAndroidClient.setBufferOpts(disconnectedBufferOptions);
                    subscribeToTopic();
                    Toast.makeText(MainActivity.this,"onSuccess",Toast.LENGTH_SHORT).show();
                }

                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                    Log.i("paho","Failed to connect to:" + serverUri);
                    Toast.makeText(MainActivity.this,"onFailure",Toast.LENGTH_SHORT).show();

                }
            });

        } catch (MqttException ex){
            ex.printStackTrace();
        }
    }


    public void subscribeToTopic(){
        try {
            mqttAndroidClient.subscribe(topics, new int[]{0,0}, null, new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {
                    Log.i("paho","Subscribed");
                }

                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {

                }
            });

            mqttAndroidClient.subscribe(topics, new int[]{0,0},new IMqttMessageListener[]{
                    new IMqttMessageListener() {//抓拍
                        @Override
                        public void messageArrived(String topic, MqttMessage message) throws Exception {
                            //在这里处理接收到第一个订阅主题的消息
                            System.out.println("抓拍 Message: " + topic + " : " + new String(message.getPayload()));
                        }
                    },
                    new IMqttMessageListener() {//比对成功
                        @Override
                        public void messageArrived(String topic, MqttMessage message) throws Exception {
                             //在这里处理接收到第二个订阅主题的消息
                            System.out.println("比对成功 Message: " + topic + " : " + new String(message.getPayload()));
                        }
                    }

            });

        } catch (MqttException ex){
            System.err.println("Exception whilst subscribing");
            ex.printStackTrace();
        }
    }

4.总结

如果你需要做Android消息推送的话,你可以继续研究paho里面的例子。我只是抛砖引玉:
MQTT和ActiveMQ
MQTT协议中文版
深入浅出JMS(二)–ActiveMQ简单介绍以及安装

猜你喜欢

转载自blog.csdn.net/wanliguodu/article/details/82703229