eclipse / paho.mqtt.rust

paho.mqtt.rust
Other
525 stars 102 forks source link

AsyncClient::new hangs when called multiple times #207

Open tross-skybell opened 1 year ago

tross-skybell commented 1 year ago

I have the following code to initialize mqtt: (Note: I have broken create_client() into its calls to help identify where it is stuck)

pub fn mqtt_rx_init( connect_timeout: &mut u64, client_id: String, ca_path: String, client_cert_path: String, client_key_path: String, aws_iot_endpoint: String ) -> Result<mqtt::AsyncClient, mqtt::Error>
{
  let mqtt_client;
  //log_Info!(log::Module::Cloud, "mqtt_rx_init - CreateOptionsBuilder");
  let options_builder = mqtt::CreateOptionsBuilder::new()
      .server_uri(&host)
      .client_id(client_id.clone())
      .max_buffered_messages(100)
      .persistence(mqtt::PersistenceType::None);

  //log_Info!(log::Module::Cloud, "mqtt_rx_init - options finalize");
  let create_options = options_builder.finalize();

  //log_Info!(log::Module::Cloud, "mqtt_rx_init - AsyncClient");
  match mqtt::AsyncClient::new(create_options)
  {
      Ok(client) =>
      {
          mqtt_client = client;
      },
      Err(e) =>
      {
          log_Err!(log::Module::Cloud, "MQTT Create error: {:?}", e);
          return Err(e);
      },
  }

  //log_Info!(log::Module::Cloud, "mqtt_rx_init - SslOptionsBuilder");
  let ssl_opts = mqtt::SslOptionsBuilder::new()
      .trust_store(ca_path).unwrap()
      .key_store(client_cert_path).unwrap()
      .private_key(client_key_path).unwrap()
      .finalize();

  //log_Info!(log::Module::Cloud, "mqtt_rx_init - ConnectOptionsBuilder");
  let conn_opts = mqtt::ConnectOptionsBuilder::new()
      .ssl_options(ssl_opts)
      .connect_timeout(time::Duration::from_millis(*connect_timeout))
      .keep_alive_interval(time::Duration::from_secs(AWS_IOT_KEEPALIVE_TIME))
      .automatic_reconnect(time::Duration::from_millis(AWS_IOT_RECONNECT_DELAY_TIME_MSEC), time::Duration::from_secs(AWS_IOT_KEEPALIVE_TIME))
      .clean_session(true)
      .clean_start(false)
      .finalize();
  //log_Info!(log::Module::Cloud, "MqttClient starting with timeout {}", *connect_timeout);

  let result = mqtt_client.connect(conn_opts).wait();
  match result
  {
      Ok(_) =>
      {
          //log_Info!(log::Module::Cloud, "MqttClient started: {:?}", result);
      },
      Err(e) =>
      {
          //log_Err!(log::Module::Cloud, "MqttClient start error: {:?}", e);
          return Err(e);
      },
  }

  return Ok(mqtt_client);
}

In the case where the device is offline and cannot connect this code runs about 1/minute and fails immediately with "TCP/TLS connect failure". After a few tries however it gets stuck inside AsyncClient::new() which never returns.

Looking at the AsyncClient code it isn't clear where it is getting stuck.

RockyGitHub commented 1 year ago

I also have issues with connect() never returning, as well as .is_connected().