@@ -39,6 +39,10 @@ void AdafruitIO::connect()
3939{
4040
4141 AIO_DEBUG_PRINTLN (" AdafruitIO::connect()" );
42+
43+ _last_mqtt_connect = 0 ; // need to start over fresh
44+ _status = AIO_IDLE;
45+ _last_ping = 0 ;
4246
4347 if (_err_sub) {
4448 // setup error sub
@@ -165,18 +169,28 @@ const __FlashStringHelper* AdafruitIO::statusText()
165169 }
166170}
167171
168- aio_status_t AdafruitIO::run (uint16_t busywait_ms)
172+ aio_status_t AdafruitIO::run (uint16_t busywait_ms, bool fail_fast )
169173{
170174 uint32_t timeStart = millis ();
171- // If we aren't network connected, return status -- fail quickly
172- if (status () < AIO_NET_CONNECTED) {
173- return status ();
175+ if (status () < AIO_NET_CONNECTED) { // If we aren't network connected...
176+ if (fail_fast) return status (); // return status and fail quickly
177+ else { // or try to reconnect from the start
178+ AIO_ERROR_PRINT (" run() connection failed -- retrying" );
179+ unsigned long started = millis ();
180+ connect ();
181+ // wait for a full AIO connection then carry on
182+ while (status () < AIO_CONNECTED) {
183+ // or return an error if the reconnection times out
184+ if (millis () - started > AIO_NET_CONNECTION_TIMEOUT) return status ();
185+ delay (500 );
186+ }
187+ }
174188 }
175189
176190 // loop until we have a connection
177191 // mqttStatus() will try to reconnect before returning
178- while (mqttStatus () != AIO_CONNECTED && millis () - timeStart < AIO_MQTT_CONNECTION_TIMEOUT){}
179- if (mqttStatus () != AIO_CONNECTED) return status ();
192+ while (mqttStatus (fail_fast ) != AIO_CONNECTED && millis () - timeStart < AIO_MQTT_CONNECTION_TIMEOUT){}
193+ if (mqttStatus (fail_fast ) != AIO_CONNECTED) return status ();
180194
181195 if (busywait_ms > 0 )
182196 _packetread_timeout = busywait_ms;
@@ -237,7 +251,7 @@ char* AdafruitIO::userAgent()
237251 return _user_agent;
238252}
239253
240- aio_status_t AdafruitIO::mqttStatus ()
254+ aio_status_t AdafruitIO::mqttStatus (bool fail_fast )
241255{
242256 // if the connection failed,
243257 // return so we don't hammer IO
@@ -251,21 +265,26 @@ aio_status_t AdafruitIO::mqttStatus()
251265 if (_mqtt->connected ())
252266 return AIO_CONNECTED;
253267
254- switch (_mqtt->connect (_username, _key)) {
255- case 0 :
256- return AIO_CONNECTED;
257- case 1 : // invalid mqtt protocol
258- case 2 : // client id rejected
259- case 4 : // malformed user/pass
260- case 5 : // unauthorized
261- return AIO_CONNECT_FAILED;
262- case 3 : // mqtt service unavailable
263- case 6 : // throttled
264- case 7 : // banned -> all MQTT bans are temporary, so eventual retry is permitted
265- // delay to prevent fast reconnects
266- delay (AIO_THROTTLE_RECONNECT_INTERVAL);
267- return AIO_DISCONNECTED;
268- default :
269- return AIO_DISCONNECTED;
268+ // prevent fast reconnect attempts, except for the first time through
269+ if (_last_mqtt_connect == 0 || millis () - _last_mqtt_connect > AIO_THROTTLE_RECONNECT_INTERVAL){
270+ _last_mqtt_connect = millis ();
271+ switch (_mqtt->connect (_username, _key)) {
272+ case 0 :
273+ return AIO_CONNECTED;
274+ case 1 : // invalid mqtt protocol
275+ case 2 : // client id rejected
276+ case 4 : // malformed user/pass
277+ case 5 : // unauthorized
278+ return AIO_CONNECT_FAILED;
279+ case 3 : // mqtt service unavailable
280+ case 6 : // throttled
281+ case 7 : // banned -> all MQTT bans are temporary, so eventual retry is permitted
282+ // delay to prevent fast reconnects and fast returns (backward compatibility)
283+ if (!fail_fast) delay (AIO_THROTTLE_RECONNECT_INTERVAL);
284+ return AIO_DISCONNECTED;
285+ default :
286+ return AIO_DISCONNECTED;
287+ }
270288 }
289+ return AIO_DISCONNECTED;
271290}
0 commit comments