MQTT basado en el uso de Android

prefacio

Anterior MQTT menciona de manera general, ya que el proyecto de la red de las fluctuaciones frecuentes en el hogar TV inteligente, enfoque común ha sido incapaz de satisfacer la demanda, a menudo resulta en la duplicación suscribirse para recibir más de un mensaje, sólo puede abrir un nuevo camino, y finalmente encontró MqttAndroidClient soñar.

1. Integración

Y en un enfoque integrado y el uso de MQTT Introducción a la nueva configuración, build.gradle nueva

 

implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'

archivo de manifiesto que requiere el servicio de registro

 

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

2.MqttAndroidClient importante fuente de análisis sintáctico

MqttAndroidClient está diseñado para expandir el reembalado de clases MQTTClient, incluyendo la suscripción, multi-threading y está conectado directamente con el paquete para ver la fuente MqttAndroidClient conectado con el código no crítica se ha omitido

 

    public IMqttToken connect(MqttConnectOptions options, Object userContext,
            IMqttActionListener callback) throws MqttException {
        if (mqttService == null) { 
        }
        else {
            pool.execute(new Runnable() {
                @Override
                public void run() {
                    doConnect();
                }
            });
        }
        return token;
    }

doConnect () operación en la conexión de sub-hilo, prevenir eficazmente las fluctuaciones en la conexión de red bloquear el hilo principal prolongada

 

private void doConnect() {
        ...
            mqttService.connect(clientHandle, connectOptions, null,
                    activityToken);
        ...
    }

Ali escrito específicamente para el cliente de Android un MQTTService, gestión unificada conveniente, además de conectar operación, volver a conectar, desconectar se realiza en MQTTService en.

 

public void connect(String clientHandle, MqttConnectOptions connectOptions,
      String invocationContext, String activityToken)throws MqttSecurityException, MqttException {
        MqttConnection client = getConnection(clientHandle);
        client.connect(connectOptions, null, activityToken);
  }

 

public void connect(MqttConnectOptions options, String invocationContext,
            String activityToken) {
            ...
            if (myClient != null) {
                if (isConnecting ) {
                }else if(!disconnected){
                }
                else {                  
                    service.traceDebug(TAG, "myClient != null and the client is not connected");
                    service.traceDebug(TAG,"Do Real connect!");
                    setConnectingState(true);
                    myClient.connect(connectOptions, invocationContext, listener);
                }
            }
            ...
    }

 

public IMqttToken connect(MqttConnectOptions options, Object userContext, IMqttActionListener callback)throws MqttException, MqttSecurityException {
        final String methodName = "connect";
        if (comms.isConnected()) {
            throw ExceptionHelper.createMqttException(MqttException.REASON_CODE_CLIENT_CONNECTED);
        }
        if (comms.isConnecting()) {
            throw new MqttException(MqttException.REASON_CODE_CONNECT_IN_PROGRESS);
        }
        if (comms.isDisconnecting()) {
            throw new MqttException(MqttException.REASON_CODE_CLIENT_DISCONNECTING);
        }
        if (comms.isClosed()) {
            throw new MqttException(MqttException.REASON_CODE_CLIENT_CLOSED);
        }
        ...
        connectActionListener.connect();
        return userToken;
    }

Fuente sí para isConnected, isConnecting, isDisconnecting, isClosed hacer la gestión de excepciones a la conexión de evitar que resulta en conexión duplicación está siendo conectado o desconectado. No más tarde publicado el código fuente necesario, es abrir un hilo de conexión.

uso 3.MqttAndroidClient

Para completar la línea de conexión de código MQTT

 

mqttAndroidClient.connect(mqttConnectOptions, null, iMqttActionListener);

Por supuesto, esto no es suficiente, se encontró que en las aplicaciones prácticas que hay un problema, después de algún tiempo la reconexión a la red a la red MQTT no lo hace volver a conectar automáticamente, por lo que tenemos que hacer la optimización manual. La idea es muy simple, hilos de reconexión abiertas nodo hilo desconectado, vuelva a conectar cerrado después de una conexión exitosa. El siguiente es el código de pegatinas completos, el principal mecanismo de la atención antes de la reconexión y recordar a suscribir darse de baja y luego suscribirse. (Sección contiene su propio código, puede pasar por alto, notas en gran detalle)

 

public class MQTTManager {

    private Context mContext;
    private MqttAndroidClient mqttAndroidClient;
    private String clientId;//自定义

    private MqttConnectOptions mqttConnectOptions;

    private ScheduledExecutorService reconnectPool;//重连线程池

    public MQTTManager(Context mContext) {
        this.mContext = mContext;
    }

    public void buildClient() {
        closeMQTT();//先关闭上一个连接

        buildMQTTClient();
    }

    private IMqttActionListener iMqttActionListener = new IMqttActionListener() {
        @Override
        public void onSuccess(IMqttToken asyncActionToken) {
            TVLog.i("connect-"+"onSuccess");
            closeReconnectTask();
            subscribeToTopic();
        }

        @Override
        public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
            //connect-onFailure-MqttException (0) - java.net.UnknownHostException
            TVLog.i("connect-"+ "onFailure-"+exception);
            startReconnectTask();
        }
    };

    private MqttCallback mqttCallback = new MqttCallback() {
        @Override
        public void connectionLost(Throwable cause) {
            //close-connectionLost-等待来自服务器的响应时超时 (32000)
            //close-connectionLost-已断开连接 (32109)
            TVLog.i("close-"+"connectionLost-"+cause);
            if (cause != null) {//null表示被关闭
                startReconnectTask();
            }
        }

        @Override
        public void messageArrived(String topic, MqttMessage message) throws Exception {
            String body = new String(message.getPayload());
            TVLog.i("messageArrived-"+message.getId()+"-"+body);
        }

        @Override
        public void deliveryComplete(IMqttDeliveryToken token) {
            try {
                TVLog.i("deliveryComplete-"+token.getMessage().toString());
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
    };

    private void buildMQTTClient(){
        mqttAndroidClient = new MqttAndroidClient(mContext, MQTTCons.Broker, clientId);
        mqttAndroidClient.setCallback(mqttCallback);

        mqttConnectOptions = new MqttConnectOptions();
        mqttConnectOptions.setConnectionTimeout(10);
        mqttConnectOptions.setKeepAliveInterval(20);
        mqttConnectOptions.setCleanSession(true);
        try {
            mqttConnectOptions.setUserName("Signature|" + MQTTCons.AcessKey + "|" + MQTTCons.instanceId);
            mqttConnectOptions.setPassword(MacSignature.macAndSignature(clientId, MQTTCons.SecretKey).toCharArray());
        } catch (Exception e) {
        }
        doClientConnection();
    }

    private synchronized void startReconnectTask(){
        if (reconnectPool != null)return;
        reconnectPool = Executors.newScheduledThreadPool(1);
        reconnectPool.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                doClientConnection();
            }
        } , 0 , 5*1000 , TimeUnit.MILLISECONDS);
    }

    private synchronized void closeReconnectTask(){
        if (reconnectPool != null) {
            reconnectPool.shutdownNow();
            reconnectPool = null;
        }
    }

    /**
     * 连接MQTT服务器
     */
    private synchronized void doClientConnection() {
        if (!mqttAndroidClient.isConnected()) {
            try {
                mqttAndroidClient.connect(mqttConnectOptions, null, iMqttActionListener);
                TVLog.d("mqttAndroidClient-connecting-"+mqttAndroidClient.getClientId());
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
    }

    private void subscribeToTopic() {//订阅之前会取消订阅,避免重连导致重复订阅
        try {
            String registerTopic = "";//自定义
            String controlTopic = "";//自定义
            String[] topicFilter=new String[]{registerTopic , controlTopic };
            int[] qos={0,0};
            mqttAndroidClient.unsubscribe(topicFilter, null, new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {
                    TVLog.i("unsubscribe-"+"success");
                }

                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                    TVLog.i("unsubscribe-"+"failed-"+exception);
                }
            });
            mqttAndroidClient.subscribe(topicFilter, qos, null, new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {//订阅成功
                    TVLog.i("subscribe-"+"success");
                }

                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
//                    startReconnectTask();
                    TVLog.i("subscribe-"+"failed-"+exception);
                }
            });

        } catch (MqttException ex) {
        }
    }

    public void sendMQTT(String topicSep, String msg) {
        try {
            if (mqttAndroidClient == null)return;
            MqttMessage message = new MqttMessage();
            message.setPayload(msg.getBytes());
            String topic = "";//自定义
            mqttAndroidClient.publish(topic, message, null, new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {
//                    TVLog.i("sendMQTT-"+"success:" + msg);
                }

                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
//                    startReconnectTask();
                    TVLog.i("sendMQTT-"+"failed:" + msg);
                }
            });
        } catch (MqttException e) {
        }
    }

    public void closeMQTT(){
        closeReconnectTask();
        if (mqttAndroidClient != null){
            try {
                mqttAndroidClient.unregisterResources();
                mqttAndroidClient.disconnect();
                TVLog.i("closeMQTT-"+mqttAndroidClient.getClientId());
                mqttAndroidClient = null;
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
    }

}

Llamado por y quería hacer Singleton flujos seguros puede ser dueño de paquete

 

if (mqttManager == null)
            mqttManager = new MQTTManager(getApplicationContext());
mqttManager.buildClientId();

epílogo

parte basado en Android puede considerarse el final, que también se mezcla con alguna fuente explicó que el seguimiento a escribir más acerca de analizar el código fuente.



Reproducido: https: //www.jianshu.com/p/2857419d14b0

Publicado 40 artículos originales · ganado elogios 57 · Vistas de 250.000 +

Supongo que te gusta

Origin blog.csdn.net/With__Sunshine/article/details/105317659
Recomendado
Clasificación