MQTT icon indicating copy to clipboard operation
MQTT copied to clipboard

Mqtt Fails to connect

Open fcabrera23 opened this issue 7 years ago • 4 comments

Sometimes the client fails to connect for some time. I have to reset Electron so that the entire connection restarts ( i've checked and the internet connectivity is ok and even send a mqtt.disconnect() before trying a connection). Could it be clean session needed? Thanks

fcabrera23 avatar Aug 13 '17 16:08 fcabrera23

Parameters :

char server[] = "m13.cloudmqtt.com"; // Servevor Mqtt Nuevo int portMqtt = 18509; char* clientId ="73122"; char* username = "73122"; char* password= "dfk;lfsdg"; MQTT mqttClient(server, portMqtt,30,callbackMQTT);

Basically this is my loop

 if (Cellular.ready())
{
    digitalWrite(ledGPRS,0);
    attempts = 0;
    if (mqttClient.isConnected()) {
        mqttClient.loop();
 } else {
        Serial.println("Connect to the MQTT server!!");
        mqttClient.connect(clientId,username,password);
        if (mqttClient.isConnected()) {
            Serial.println("Connected");
            mqttClient.addQosCallback(qoscallback);
            mqttClient.publish("reconnections", celu.imei);
        }
    }
}
else
{
    digitalWrite(ledGPRS,1);
    if(attempts > 10){ // Si ya probe 10 (mas de 50 minutos intentando la conexion) veces la conexion y no tuve exito
        System.reset();
    }
    
    if ((millis() - lastConnect) >= CONNECT_TIMEOUT)
    {
        if(bomba_encendida == APAGADO) // Si la bomab esta desconectada
        {
            Cellular.disconnect();
            Cellular.off();
            delay(5000);
            debug < 1 ? debug=0:Serial.println("Intento conectar modem celular.");
            Cellular.on();
            Cellular.connect();
            lastConnect = millis();
            attempts++;
        }
    }
}

Sometimes it connects, but if reset it, when trying again , won't connect again

I was able to get the log from CloudMqtt:

1502718718: New connection from 179.29.45.169 on port 18509. 1502718726: New connection from 179.29.45.169 on port 18509. 1502718734: New connection from 179.29.45.169 on port 18509. 1502718747: New connection from 179.29.45.169 on port 18509. 1502718754: New connection from 179.29.45.169 on port 18509. 1502718762: New connection from 179.29.45.169 on port 18509. 1502718770: New connection from 179.29.45.169 on port 18509. 1502718778: New connection from 179.29.45.169 on port 18509. 1502718786: New connection from 179.29.45.169 on port 18509. 1502718793: New connection from 179.29.45.169 on port 18509. 1502718801: New connection from 179.29.45.169 on port 18509. 1502718809: New connection from 179.29.45.169 on port 18509. 1502718817: New connection from 179.29.45.169 on port 18509. 1502718825: New connection from 179.29.45.169 on port 18509. 1502718858: New connection from 179.29.45.169 on port 18509. 1502718991: New connection from 179.29.45.169 on port 18509. 1502719150: New connection from 179.29.45.169 on port 18509.

fcabrera23 avatar Aug 14 '17 15:08 fcabrera23

I also have this issue running the example mqtttest.ino on the Photon. Could the issue be on the TCPClient lib?

imomo0 avatar Sep 27 '17 06:09 imomo0

@imomo0 Update and try new firmware version.

hirotakaster avatar Nov 06 '17 01:11 hirotakaster

I had a similar issue when dealing with flaky WiFi connections and had to implement a write timeout in the library, this seems to solve the problem so far. I based my changes off an older version so would need to re-port it before doing a pull request. If this is useful to someone I can try to port it sooner so they can test my changes. If someone else wants to do the port here are some of the changes I did:

I replaced all _client.write(...) with this:

bool MQTT::writeBuffer(const uint8_t *b, size_t s) {
    if ( timeout = 0) {
        size_t rlen = _client.write(&b[ptr],s-ptr,tout);
        if (_client.getWriteError() != 0 ) {
            break;
        }
        ptr +=rlen;
        tout = (system_tick_t)timeout+(system_tick_t)start-(system_tick_t)millis();
    }
    if ( ptr != s ) {
        _client.stop();
        return false;
    }
    return true;
}

This now returns true/false so the MQTT::write(..) needs to check for true instead of comparing the length.

I added a setter for timeout and defaulted it to -1 so the behavior is not changed if you don't set a timeout.

I allow for a timeout of 0 which is truly non blocking but don't think it is useful, you need to use a more complex Async stye library if you want pure non blocking.

My testing was done with a timeout of 5000 (5 seconds)

NOTE: When adding timeout to the TCPClient.write you need that loop given it will return even when only part of the data is written.

leafgarden avatar May 01 '21 18:05 leafgarden