【问题标题】:Trying Mqtt connection on Android using Paho MqttClient使用 Paho MqttClient 在 Android 上尝试 Mqtt 连接
【发布时间】:2017-02-12 15:44:51
【问题描述】:

当您第一次打开应用程序时,我想要一个屏幕,您可以在其中输入经纪人信息并单击尝试并保存。

点击尝试时,它应该只显示一个Snackbar,说明该信息是否可以成功连接。

这是我按下 try 按钮时调用的代码:

private void tryConnection(View v){
    if(verifyInputs()){
        Snackbar.make(v, getString(R.string.trying_connection), Snackbar.LENGTH_LONG).show();

        String clientId = MqttClient.generateClientId();
        MqttAndroidClient client =
                new MqttAndroidClient(this.getApplicationContext(), getServerAddress(),
                        clientId);

        try {
            IMqttToken token = client.connect();
            final View vinner = v;
            token.setActionCallback(new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {
                    // We are connected
                    Snackbar.make(vinner, "Success", Snackbar.LENGTH_LONG).show();

                }

                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                    // Something went wrong e.g. connection timeout or firewall problems
                    Snackbar.make(vinner, "Fail", Snackbar.LENGTH_LONG).show();
                }
            });
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }
}

问题是,onFailure 在无法连接到服务器时似乎没有被调用,而是在与服务器的连接丢失时。

如何测试连接,以便存储它并返回到主要活动?

【问题讨论】:

    标签: android connection mqtt paho


    【解决方案1】:

    好的,所以我看不到您的完整服务、任何其他实现或您使用它的方式/位置,因此我提供了我的 MQTT 服务的示例。

    也许你可以比较一下,发现任何问题并修复它。

    或者你可以使用我的实现。由你决定。希望对您有所帮助。

    import android.app.Service;
    import android.content.Intent;
    import android.os.Binder;
    import android.os.Handler;
    import android.os.IBinder;
    import android.support.annotation.Nullable;
    import android.util.Log;
    
    import org.eclipse.paho.android.service.MqttAndroidClient;
    import org.eclipse.paho.client.mqttv3.IMqttActionListener;
    import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
    import org.eclipse.paho.client.mqttv3.IMqttToken;
    import org.eclipse.paho.client.mqttv3.MqttCallback;
    import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
    import org.eclipse.paho.client.mqttv3.MqttException;
    import org.eclipse.paho.client.mqttv3.MqttMessage;
    import org.eclipse.paho.client.mqttv3.MqttSecurityException;
    import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
    
    import java.util.ArrayList;
    
    public class MyMqttService extends Service implements MqttCallback, IMqttActionListener {
    
        private final IBinder binder = new MyBinder();
    
        private MqttAndroidClient mqttClient;
        private MqttConnectOptions mqttConnectOptions;
        private static final MemoryPersistence persistence = new MemoryPersistence();
        private ArrayList<MqttAndroidClient> lostConnectionClients;
    
        private String clientId = "";
        private boolean isReady = false;
        private boolean doConnectTask = true;
        private boolean isConnectInvoked = false;
    
        private Handler handler = new Handler();
        private final int RECONNECT_INTERVAL = 10000; // 10 seconds
        private final int DISCONNECT_INTERVAL = 20000; // 20 seconds
        private final int CONNECTION_TIMEOUT = 60;
        private final int KEEP_ALIVE_INTERVAL = 200;
    
        private String broker_url = "my_broker";
    
        public MyMqttService() {}
    
        public class MyBinder extends Binder {
            public MyMqttService getService() {
                return MyMqttService.this;
            }
        }
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return binder;
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            initMqttClient();
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
    
            disconnectClients();
            if (isConnectInvoked && mqttClient != null && mqttClient.isConnected()) {
                try {
                    // unsubscribe here
                    unsubscribe("¯\\_(ツ)_/¯");
                    mqttClient.disconnect();
                } catch (MqttException e) {
                    Log.e("TAG", e.toString());
                }
            }
    
            handler.removeCallbacks(connect);
            handler.removeCallbacks(disconnect);
        }
    
        private void initMqttClient() {
            if(mqttClient != null) {
                mqttClient = null;
            }
    
            lostConnectionClients = new ArrayList<>();
    
            mqttConnectOptions = new MqttConnectOptions();
            mqttConnectOptions.setCleanSession(true);
            mqttConnectOptions.setConnectionTimeout(CONNECTION_TIMEOUT);
            mqttConnectOptions.setKeepAliveInterval(KEEP_ALIVE_INTERVAL);
    
            setNewMqttClient();
    
            handler.post(connect);
            handler.postDelayed(disconnect, DISCONNECT_INTERVAL);
        }
    
        private void setNewMqttClient() {
            mqttClient = new MqttAndroidClient(MyMqttService.this, broker_url, clientId, persistence);
            mqttClient.setCallback(this);
        }
    
        public Runnable connect = new Runnable() {
            public void run() {
                connectClient();
                handler.postDelayed(connect, RECONNECT_INTERVAL);
            }
        };
    
        public Runnable disconnect = new Runnable() {
            public void run() {
                disconnectClients();
                handler.postDelayed(disconnect, DISCONNECT_INTERVAL);
            }
        };
    
        private void connectClient() {
            if(doConnectTask) {
                doConnectTask = false;
    
                try {
                    isConnectInvoked = true;
                    mqttClient.connect(mqttConnectOptions, null, this);
                } catch (MqttException ex) {
                    doConnectTask = true;
                    Log.e("TAG", ex.toString());
                }
            }
        }
    
        private void disconnectClients() {
            if (lostConnectionClients.size() > 0) {
                // Disconnect lost connection clients
                for (MqttAndroidClient client : lostConnectionClients) {
                    if (client.isConnected()) {
                        try {
                            client.disconnect();
                        } catch (MqttException e) {
                            Log.e("TAG", e.toString());
                        }
                    }
                }
    
                // Close already disconnected clients
                for (int i = lostConnectionClients.size() - 1; i >= 0; i--) {
                    try {
                        if (!lostConnectionClients.get(i).isConnected()) {
                            MqttAndroidClient client = lostConnectionClients.get(i);
                            client.close();
                            lostConnectionClients.remove(i);
                        }
                    } catch (IndexOutOfBoundsException e) {
                        Log.e("TAG", e.toString());
                    }
                }
            }
        }
    
        @Override
        public void deliveryComplete(IMqttDeliveryToken token) {
            Log.e("TAG", "deliveryComplete()");
        }
    
        @Override
        public void messageArrived(String topic, MqttMessage message) throws Exception {
            String payload = new String(message.getPayload());
            // do something
        }
    
        @Override
        public void connectionLost(Throwable cause) {
            Log.e("TAG", cause.getMessage());
        }
    
        @Override
        public void onSuccess(IMqttToken iMqttToken) {
            isReady = true;
    
            // subscribe here
             subscribe("¯\\_(ツ)_/¯");
        }
    
        @Override
        public void onFailure(IMqttToken iMqttToken, Throwable throwable) {
            setNewMqttClient();
            isReady = false;
            doConnectTask = true;
            isConnectInvoked = false;
        }
    
        private void subscribe(String topic) {
            try {
                mqttClient.subscribe(topic, 0);
                isReady = true;
            } catch (MqttSecurityException mqttSexEx) {
                isReady = false;
            } catch (MqttException mqttEx) {
                isReady = false;
            }
        }
    
        private void unsubscribe(String topic) {
            try {
                mqttClient.unsubscribe(topic);
            } catch (MqttSecurityException mqttSecEx) {
                Log.e("TAG", mqttSecEx.getMessage());
            } catch (MqttException mqttEx) {
                Log.e("TAG", mqttEx.getMessage());
            }
        }
    
        private void publish(String topic, String jsonPayload) {
            if(!isReady) {
                return;
            }
    
            try {
                MqttMessage msg = new MqttMessage();
                msg.setQos(0);
                msg.setPayload(jsonPayload.getBytes("UTF-8"));
                mqttClient.publish(topic, msg);
            } catch (Exception ex) {
                Log.e("TAG", ex.toString());
            }
        }
    }
    

    我的另一个建议是设置本地广播,这样当您的活动加载并启动服务时,如果 MQTT 服务能够连接,您发送一个广播说已连接并显示Snackbar。如果连接失败,您将发送不同的广播并显示不同的消息。

    【讨论】:

    • 嗨!我正在使用您的服务,或者至少尝试使用。你能解释一下我如何订阅吗?我完全迷路了,已经为此工作了好几个小时
    • @NelsonSilva 有一个用于 MQTT 的 onSuccess 回调。与代理的连接成功后,将调用该方法。因此,您所要做的就是在那里调用subscribe 方法并将您订阅的topic 作为参数传入。您是否遇到任何错误或任何具体问题?
    • 其实我已经尝试了很多我不知道从哪里开始的事情。我一直在 youtube 上观看视频,使用“ServiceConnection”并绑定服务,但我无处可去。当我尝试订阅时,我在空对象引用上得到 >org.eclipse.paho.android.service.MqttAndroidClient.subscribe(java.lang.String, int)' 。另外,要订阅我需要一个 IMqttToken 吗?我迷路了,对不起......我不明白从服务内部调用该方法的正确方法
    • @NelsonSilva 如果没有看到您的实施,我无法确定问题。请开始一个新问题并显示您的Service 代码,以便我们查看问题所在
    • @THEPATEL 我正在使用你的代码,这就是我所拥有的......我一直在放弃其他所有东西,因为它不起作用。如果您能提供一个简单的代码 sn-p 显示如何订阅,我将不胜感激
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-19
    相关资源
    最近更新 更多