繁体   English   中英

MQTT Paho Client无法自动重新连接到Android Service上的代理

MQTT Paho Client not reconnect automatically to broker on Android Service

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

我有一个服务来管理我的MQTT客户端连接,MQTT正常运行,但是问题是当我重新启动Broker Server时,Android客户端未重新连接。 onConnectionLost()回调上触发异常。

笔记

  1. 我在同一台计算机上使用Moquette Broker-> Moquette
  2. 我有两个Android客户端应用程序,一个使用Service(有问题的),另一个在不使用Service的线程上工作(这很好,重新连接就可以了)。
  3. 我无法运行Android Client MQTT库,因为我正在使用Eclipse Paho MQTT。
  4. 是的,我将setAutomaticReconnect(true);

问题

使用Service的Android应用程序可以永久运行,而无需重新连接到MQTT Broker。

MQTTService.java

public class MQTTService extends Service implements MqttCallbackExtended {

    boolean running;
private static final String TAG = "MQTTService";

public static final String ACTION_MQTT_CONNECTED = "ACTION_MQTT_CONNECTED";
public static final String ACTION_MQTT_DISCONNECTED = "ACTION_MQTT_DISCONNECTED";
public static final String ACTION_DATA_ARRIVED = "ACTION_DATA_ARRIVED";

// MQTT
MqttClient mqttClient;
final String serverURI = "tcp://"+ServidorServices.IP+":1883";
final String clientId = "Responsavel";
String topicoId;
Thread mqttStartThread;

public boolean subscribe(String topic) {
    try {
        Log.i(TAG,"Subscripe: " + topic);
        mqttClient.subscribe(topic);
        mqttClient.subscribe("LOCATION_REAL");
        return true;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return false;
}

// Life Cycle
@Override
public IBinder onBind(Intent intent) {
    Log.d(TAG,"onBind()");
    return null;
}

@Override
public void onCreate() {
    Log.d(TAG,"onCreate()");
    running = true;
    topicoId = getSharedPreferences("myprefs",MODE_PRIVATE).getString("tag_id_aluno","0");

    mqttStartThread = new MQTTStartThread(this);

    if(topicoId.equals("0")) {
        Log.i(TAG,"Error to subscribe");
        return;
    }

    mqttStartThread.start();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.d(TAG,"onStartCommand()");
    return super.onStartCommand(intent, flags, startId);
}

class MQTTStartThread extends Thread {

    MqttCallbackExtended mqttCallbackExtended;

    public MQTTStartThread(MqttCallbackExtended callbackExtended) {
        this.mqttCallbackExtended = callbackExtended;
    }

    @Override
    public void run() {
        try {
            mqttClient = new MqttClient(serverURI,clientId,new MemoryPersistence());
            MqttConnectOptions options = new MqttConnectOptions();
            options.setAutomaticReconnect(true);
            options.setCleanSession(true);
            mqttClient.setCallback(mqttCallbackExtended);
            mqttClient.connect();
        } catch (Exception e) {
            Log.i(TAG,"Exception MQTT CONNECT: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

@Override
public void onDestroy() {
    Log.d(TAG,"onDestroy()");
    running = false;
    if (mqttClient != null) {
        try {
            if (mqttClient.isConnected()) mqttClient.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

@Override
public boolean onUnbind(Intent intent) {
    Log.i(TAG,"onUnbind()");
    return super.onUnbind(intent);
}

// Callbacks MQTT
@Override
public void connectComplete(boolean reconnect, String serverURI) {
    Log.i(TAG,"connectComplete()");
    if (topicoId == null) {
        Log.i(TAG,"Erro ao ler ID da Tag");
        return;
    }
    sendBroadcast(new Intent(ACTION_MQTT_CONNECTED));
    subscribe(topicoId);
}

@Override
public void connectionLost(Throwable cause) {
    Log.i(TAG,"connectionLost(): " + cause.getMessage());
    cause.printStackTrace();
    sendBroadcast(new Intent(ACTION_MQTT_DISCONNECTED));
}

@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
    Log.i(TAG,"messageArrived() topic: " + topic);

    if (topic.equals("LOCATION_REAL")) {
        Log.i(TAG,"Data: " + new String(message.getPayload()));
    } else {
        Context context = MQTTService.this;
        String data = new String(message.getPayload());
        Intent intent = new Intent(context,MapsActivity.class);
        intent.putExtra("location",data);
        LatLng latLng = new LatLng(Double.valueOf(data.split("_")[0]),Double.valueOf(data.split("_")[1]));
        String lugar = Utils.getAddressFromLatLng(latLng,getApplicationContext());
        NotificationUtil.create(context,intent,"Embarque",lugar,1);

        if (data.split("_").length < 3) {
            return;
        }

        double latitude = Double.valueOf(data.split("_")[0]);
        double longitude = Double.valueOf(data.split("_")[1]);
        String horario = data.split(" ")[2];

        Intent iMqttBroadcast = new Intent(ACTION_DATA_ARRIVED);
        iMqttBroadcast.putExtra("topico",String.valueOf(topic));
        iMqttBroadcast.putExtra("latitude",latitude);
        iMqttBroadcast.putExtra("longitude",longitude);
        iMqttBroadcast.putExtra("evento","Embarcou");
        iMqttBroadcast.putExtra("horario",horario);

        sendBroadcast(iMqttBroadcast);
    }
}

@Override
public void deliveryComplete(IMqttDeliveryToken token) {
    Log.i(TAG,"deliveryComplete()");
}
}

异常Stacktrace

I/MQTTService: connectionLost(): Connection lost
W/System.err: Connection lost (32109) - java.io.EOFException
W/System.err:     at org.eclipse.paho.client.mqttv3.internal.CommsReceiver.run(CommsReceiver.java:146)
W/System.err:     at java.lang.Thread.run(Thread.java:818)
W/System.err: Caused by: java.io.EOFException
W/System.err:     at java.io.DataInputStream.readByte(DataInputStream.java:77)
W/System.err:     at org.eclipse.paho.client.mqttv3.internal.wire.MqttInputStream.readMqttWireMessage(MqttInputStream.java:65)
W/System.err:     at org.eclipse.paho.client.mqttv3.internal.CommsReceiver.run(CommsReceiver.java:107)
W/System.err:   ... 1 more
2 个回复

如方法说明所述。

  options.setAutomaticReconnect(true);

客户端将尝试重新连接到服务器。 它最初将等待1秒钟,然后再尝试重新连接,对于每次失败的重新连接尝试,延迟将增加一倍,直到2分钟为止,此时延迟将保持2分钟。

另一个选择是您可以在发生连接丢失事件的情况下管理重试间隔。

我认为您忘记了在MqttClient对象中包含MqttConnectOptions

请尝试以下

mqttClient.connect(options);

代替

mqttClient.connect();

希望它可以解决您的重新连接问题。

1 如何使用 Paho 驱动程序重新连接到 MQTT

我正在为我的一些应用程序使用 MQTT 客户端 Java 库,并且我认为我以错误的方式重新连接到代理。 现在我有一个类来处理 MQTT 操作,如连接、断开连接、发布和订阅。 但它似乎在尝试重新连接时打开了许多连接,并使代理出现错误。 重新连接到 MQTT 代理的最佳方式是什么? ...

4 在AWS EC2 ubuntu实例上使用自己的mosquitto代理时,重新连接到mqtt代理失败

我之前在我的esp8266上使用了蚊子测试mqtt经纪人(即test.mosquitto.org)并重新连接代码,即如果连接因路由器重置而中断,那么当互联网恢复时它将重新连接到经纪人。 它的工作正常。 我在Cloud Mqtt经纪人中使用了相同的代码,它也运行得很好。 但是现在当我在AWS ...

6 在客户端重新连接到mqtt代理后获取所有消息

我正在尝试使用MQTT构建即时消息应用程序。 但是我遇到了一个障碍,因为当客户端离线一段时间后重新连接时,我无法接收发布者发送的所有消息 。 客户端通过以下设置连接到代理: 客户编号 干净的会话-错误 接收QoS 2 发布者使用以下设置发送邮件时: ...

7 重新连接到代理后,MQTT 客户端 connectionLost 不起作用

我是 MQTT 的新手。 当客户端失去连接时,我尝试重新连接到代理。 这是我的功能: 这是重新连接的功能: 在第一次代理重启时它工作正常。 但是,这个connectionLost()触发器在我第二次重新启动代理时不起作用。 我该如何解决? 非常感谢。 ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2022 STACKOOM.COM