【问题标题】:Java Eclipse Paho Implementation - Auto reconnectJava Eclipse Paho 实现 - 自动重新连接
【发布时间】:2016-02-17 12:49:27
【问题描述】:

我正在尝试在我的项目中实现eclipse.paho 以连接 Mqtt Broker(订阅和发布目的)。问题是,当我使用订阅功能(实现MqttCallback 接口)时,我无法弄清楚如果连接丢失如何重新连接。 MqttCallback 接口有一个 connectionLost 方法,但它对于调试导致连接丢失的原因很有用。我搜索但找不到建立自动重新连接的方法。你能就这个问题提出一种方法或文件吗?

【问题讨论】:

    标签: java eclipse mqtt paho


    【解决方案1】:

    做到这一点的最佳方法是构建连接逻辑,使其独立存在于方法中,以便可以从MqttCallback 实例中的connectionLost 回调再次调用它。

    connectionLost 方法被传递了一个 Throwable,这将是触发断开连接的异常,因此您可以就根本原因以及重新连接时/如何重新连接可能产生的影响做出决定。

    连接方法应该连接并订阅您需要的主题。

    类似这样的:

    public class PubSub {
    
      MqttClient client;
      String topics[] = ["foo/#", "bar"];
      MqttCallback callback = new MqttCallback() {
        public void connectionLost(Throwable t) {
          this.connect();
        }
    
        public void messageArrived(String topic, MqttMessage message) throws Exception {
          System.out.println("topic - " + topic + ": " + new String(message.getPayload()));
        }
    
        public void deliveryComplete(IMqttDeliveryToken token) {
        }
      };
    
      public static void main(String args[]) {
        PubSub foo = new PubSub();
      }
    
      public PubSub(){
        this.connect();
      }
    
      public void connect(){
        client = new MqttClient("mqtt://localhost", "pubsub-1");
        client.setCallback(callback);
        client.connect();
        client.subscribe(topics);
      }
    
    }
    

    【讨论】:

    • 对新问题提出新问题
    • 我可能来不及参加这个聚会...一旦调用 MqttCallback::connectionLost ,它将尝试再次连接。如果网络仍然关闭,则连接尝试将失败。所以到那时 Mqtt 部分将停止尝试(我假设)。当网络恢复调用连接时,有什么好方法可以做下一部分? (BroadcastReceiver onReceive?)
    • 本问答与安卓无关。请提出一个新问题
    【解决方案2】:

    我正在使用 paho 客户端 1.2.0。 使用 MqttClient.setAutomaticReconnect(true) 和接口 MqttCallbackExtended API,感谢https://github.com/eclipse/paho.mqtt.java/issues/493,当与代理的连接断开时,我可以设法自动重新连接。

    见下面的代码。

    //Use the MqttCallbackExtended to (re-)subscribe when method connectComplete is invoked
    public class MyMqttClient implements MqttCallbackExtended {
        private static final Logger logger = LoggerFactory.getLogger(MqttClientTerni.class);
        private final int qos = 0;
        private String topic = "mytopic";
        private MqttClient client;
    
        public MyMqttClient() throws MqttException {
            String host = "tcp://localhost:1883";
            String clientId = "MQTT-Client";
    
            MqttConnectOptions conOpt = new MqttConnectOptions();
            conOpt.setCleanSession(true);
            //Pay attention here to automatic reconnect
        conOpt.setAutomaticReconnect(true);
            this.client = new org.eclipse.paho.client.mqttv3.MqttClient(host, clientId);
            this.client.setCallback(this);
            this.client.connect(conOpt);
        }
    
        /**
         * @see MqttCallback#connectionLost(Throwable)
         */
        public void connectionLost(Throwable cause) {
            logger.error("Connection lost because: " + cause);
    
    
        /**
         * @see MqttCallback#deliveryComplete(IMqttDeliveryToken)
         */
        public void deliveryComplete(IMqttDeliveryToken token) {
        }
    
        /**
         * @see MqttCallback#messageArrived(String, MqttMessage)
         */
        public void messageArrived(String topic, MqttMessage message) throws MqttException {
            logger.info(String.format("[%s] %s", topic, new String(message.getPayload())));
        }
    
        public static void main(String[] args) throws MqttException, URISyntaxException {
            MyMqttClient s = new MyMqttClient();
        }
    
        @Override
        public void connectComplete(boolean arg0, String arg1) {
            try {
          //Very important to resubcribe to the topic after the connection was (re-)estabslished. 
          //Otherwise you are reconnected but you don't get any message
            this.client.subscribe(this.topic, qos);
            } catch (MqttException e) {
                e.printStackTrace();
            }
    
        }
    }
    

    【讨论】:

      【解决方案3】:

      要使用自动重新连接,只需在 MqttConnectOptions 对象上设置 setAutomaticReconnect(true)

      MqttAndroidClient mqttClient = new MqttAndroidClient(context, mqttUrl, clientId);
      
      MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
      mqttConnectOptions.setAutomaticReconnect(true);
      
      mqttClient.connect(mqttConnectOptions, null, mqttActionListener());
      

      【讨论】:

      • 我用自动重新连接尝试了这个解决方案。仍然出现连接错误。我使用 mosquitto docker 代理,因此很容易停止和启动代理。还有其他缺少的配置来完成这项工作吗?
      • 这行不通。回调 get 被调用一次,抛出一个错误,然后 paho 似乎死了。
      • @Gadi - 确保您的 clientId 是唯一的。我现在正在尝试在末尾放置一个截断的时间戳,并在断开连接时清除 clientId。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多