paho.mqtt.javascript icon indicating copy to clipboard operation
paho.mqtt.javascript copied to clipboard

Reconnection failed : trying to add reconnect Paho mqtt

Open kindthr opened this issue 4 years ago • 1 comments

I'm trying to reconnect after lost connection using javascript (React native)

 const client = new Paho.MQTT.Client(host, Number(port), clientID);
    client.onMessageArrived = this.onMessageArrived;
    client.onConnectionLost = this.onConnectionLost;
    client.connect({ 
           cleanSession : false, 
                onSuccess : this.onConnect, 
                userName: "user",
                password: "pass",
                onFailure : this.onConnectionLost, 
              
                reconnect : true,         // Enable automatic reconnect
                reconnectInterval: 10     // Reconnect attempt interval : 10 seconds
    });
onConnect = () => {
    const { client } = this.state;
    console.log("Connected!!!!");
    this.setState({isConnected: true, error: ''});
    client.subscribe(topic, qos=1);
    client.subscribe(topic1, qos=1);
    client.subscribe(topic2, qos=1);
  };

  onConnectionLost(responseObject) {
    if (responseObject.errorCode !== 0) {
      console.log("onConnectionLost : "+responseObject.errorMessage);
      this.setState({error: 'Lost Connection', isConnected: false});
    }
  }

Error: Unknown property, reconnectInterval. Valid properties are: timeout userName password willMessage keepAliveInterval cleanSession useSSL invocationContext onSuccess onFailure hosts ports reconnect mqttVersion mqttVersionExplicit uris

kindthr avatar Dec 04 '21 13:12 kindthr

reconnect interval is not a valid option. To reconnect the recommendations from other issues are use one but not both of:

  1. Call client.connect inside onConnectionLost
  2. set reconnect : true

Anyway these two will only reconnect once or twice but if your broker is down for longer your app may not reconnect. Try this yourself.

If you want something to persistently try to reconnect in react you need to code it yourself carefully, without methods 1 or 2 described above as these conflict with custom reconnect logic. Something like this worked for me:

Someting to think about is not put render changing callbacks on the success or error callbacks as these can't be removed unlike the other callbacks assigned by mutation


const healthCheckSeconds = 10;
const SomeComponent = ()=>{
   const [client] = React.useState(
    new Client(
      "localhost",
      9001,
      "random-user"
    )
  );
  
  const connectClient = React.useCallback(()=>{
    client.onMessageArrived = myCallback;
    client.connect({
        userName: "username",
        password: "username",
        })
  }, [client])
  
  React.useEffect(()=>{
    let continousFailures = 0;
    
    connectClient();

   
    
    const healthCheck  = setInterval(()=>{
      // if you have been offline for some time reconnect
      if (continousFailures === 10) {
        connectClient();
        continousFailures = 0;
        return;
      }
      // if your client is connected reset the count of continous failures
      if (client.isConnected()) {
        continousFailures = 0;
      } else {
        continousFailures++;
      }
    }, healthCheckSeconds *1000 )
    
    return ()=>{
      clearInterval(healthCheck );
      // do some cleanup of all your callbacks or they may trigger unwanted events or rerenders if they change state
      client.onMessageArrived = ()=>{}
      if(client.isConnected()){
         client.disconnect()
      }
    }
  }, [client])

  return <div>hello world</div>
}



CarlosBalladares avatar Mar 23 '22 05:03 CarlosBalladares