Closed linxingyang closed 3 years ago
Please don't paste long log contents into issues - attach them as files - it makes the issues hard to read. The issue template requests this.
You don't show where you set the callbacks. There isn't a reconnect callback is there? There is connectionLost() and connected() - do you mean one of those? Are you using automatic reconnect?
Thank you for reply and sorry for that.
reconnect-3.log reconnect-4.log
You don't show where you set the callbacks. There isn't a reconnect callback is there? There is connectionLost() and connected() - do you mean one of those?
i set the callbacks in the connect function, is there a way to set reconnect callback in MQTTAsyc_* APIs ? i think reconnect will trigger onMqttConnected like connect. as the MQTTAsync_reconnect() said
int MQTTAsync_reconnect ( MQTTAsync handle) Reconnects a client with the previously used connect options. Connect must have previously been called for this to work.
and here is the connect code.
int CWeconMqttClient::_connect(const CConnectOptions & connOpts, const CAuthenticationOptions & authOpts)
{
int nRtn = 0;
string sServerAddress, sClientId;
MQTTAsync_connectOptions mqttConnOpts = MQTTAsync_connectOptions_initializer;
MQTTAsync_SSLOptions mqttSslOpts = MQTTAsync_SSLOptions_initializer;
MQTTAsync_willOptions willOpts = MQTTAsync_willOptions_initializer;
if (existsInstance())
{
return -1;
}
m_connOpts = connOpts;
m_authOpts = authOpts;
mqttConnOpts.ssl = &mqttSslOpts;
mqttConnOpts.will = &willOpts;
if (0 > (nRtn = parseOptions(mqttConnOpts, sServerAddress, sClientId)))
{
return -2;
}
if (MQTTASYNC_SUCCESS != (nRtn = MQTTAsync_create(&m_mqtt,
sServerAddress.c_str(),
sClientId.c_str(),
MQTTCLIENT_PERSISTENCE_NONE,
NULL)))
{
printf("%s > CWeconMqttClient::_connect() -3, return code %d\n", FORMAT_DATETIME, nRtn);
return -3;
}
if (MQTTASYNC_SUCCESS != (nRtn = MQTTAsync_setConnected(m_mqtt, this, onMqttConnected)))
{
printf("%s > CWeconMqttClient::_connect() -4, return code %d\n", FORMAT_DATETIME, nRtn);
nRtn = -4;
goto _connectExit;
}
if (MQTTASYNC_SUCCESS != (nRtn = MQTTAsync_setDisconnected(m_mqtt, this, onMqttDisconnected)))
{
printf("%s > CWeconMqttClient::_connect() -5, return code %d\n", FORMAT_DATETIME, nRtn);
nRtn = -5;
goto _connectExit;
}
if (MQTTASYNC_SUCCESS != (nRtn = MQTTAsync_setCallbacks(m_mqtt, this, onMqttConnectLost, onMqttMessageArrived, onMqttMessageDelivered)))
{
printf("%s > CWeconMqttClient::_connect() -6, return code %d\n", FORMAT_DATETIME, nRtn);
nRtn = -6;
goto _connectExit;
}
if (MQTTASYNC_SUCCESS != (nRtn = MQTTAsync_connect(m_mqtt, &mqttConnOpts)))
{
printf("%s > CWeconMqttClient::_connect() -7, return code %d\n", FORMAT_DATETIME, nRtn);
nRtn = -7;
goto _connectExit;
}
_connectExit:
if (nRtn < 0)
{
_destory();
}
return nRtn;
}
Are you using automatic reconnect?
no, as Automatic Reconnect said
To switch on automatic reconnect, the connect options field automaticReconnect should be set to non-zero. The minimum and maximum times before the next connection attempt can also be set, the defaults being 1 and 60 seconds. At each failure to reconnect, the retry interval is doubled until the maximum value is reached, and there it stays until the connection is successfully re-established whereupon it is reset.
in my code, using default MQTTAsync_connectOptions_initializer, and the automaticReconnect
is set to 0.
MQTTAsync_connectOptions mqttConnOpts = MQTTAsync_connectOptions_initializer;
linxy.
Well that SSLSocket error is what you could get if the TCP connection isn't available yet. How long do you wait, how many times to do attempt a reconnect? Why don't you use automatic reconnect which would be simpler?
thank you for reply.
Well that SSLSocket error is what you could get if the TCP connection isn't available yet
so at this point, will the reconnect callback be triggered if call MQTTAsync_reconnect again ? i will try this later.
How long do you wait
wait more than 10 minutes after the 4th reconnect called. And the longest i wait is few hours in the previous tests.
how many times to do attempt a reconnect?
as you can see the CWeconMqttClient::reconnect() is block by semaphore, once connection is lost, invoker will call reconnect() repeatly until connection connected.
/**
* @details reconnect sync.
* @return
* 0 if reconnect success. \n
* -1 if instance not exists or already connected. \n
* -2 if call reconnect fail. \n
* -3 if not connected. \n */
int CWeconMqttClient::reconnect()
{
int nRtn = 0;
printf("int CWeconMqttClient::_reconnect() 1111\n");
CAutoLock autolock(m_connectionLock);
printf("int CWeconMqttClient::_reconnect() 2222\n");
if (0 > (nRtn = _reconnect()))
{
printf("int CWeconMqttClient::_reconnect() 3333\n");
return nRtn;
}
printf("int CWeconMqttClient::_reconnect() 4444\n");
m_connectionActionType = WMQTT_CONNECTION_ACTION_RECONNECT;
m_connectionSemaphore.create(1);
m_connectionSemaphore.wait(); /* block here wait for semaphore. */
printf("int CWeconMqttClient::_reconnect() 5555\n");
if (!MQTTAsync_isConnected(m_mqtt))
{
return -3;
}
printf("int CWeconMqttClient::_reconnect() 6666\n");
return 0;
}
Why don't you use automatic reconnect which would be simpler?
i want more flexible for the invoker that they can decide to reconnect after connection lost or just close the connection. if it's the problem because of the reconnect callback is not triggered, i think the automatic reconnect don't work too, right?
linxy.
As I said before, there is no reconnect callback, so I'm not sure what you are referring to here.
The callbacks are connected() and connectionLost(),
Calling reconnect() will only trigger the connected() callback if there is a successful connection, otherwise no callback will be invoked.
Calling reconnect() will only trigger the connected() callback if there is a successful connection, otherwise no callback will be invoked.
Calling reconnect() will only trigger the connected() callback if there is a successful connection, so there is no way to tell invoker when failed?
I'm consider that reconnect fail will trigger onFailure which define in struct MQTTAsync_connectOptions.
/**
* MQTTAsync_connectOptions defines several settings that control the way the
* client connects to an MQTT server. Default values are set in
* MQTTAsync_connectOptions_initializer.
*/
typedef struct
{
/**
* A pointer to a callback function to be called if the connect successfully
* completes. Can be set to NULL, in which case no indication of successful
* completion will be received.
*/
MQTTAsync_onSuccess* onSuccess;
/**
* A pointer to a callback function to be called if the connect fails.
* Can be set to NULL, in which case no indication of unsuccessful
* completion will be received.
*/
MQTTAsync_onFailure* onFailure;
} MQTTAsync_connectOptions;
linxy.
Either onSuccess or onFailure will be called once as a result of calling any command, including connect.
If you call reconnect there will only be a callback called if the connect was successful - connected(). Reconnect was mainly intended to be used with automatic reconnect. If you're not using automatic reconnect you can just call connect again - which will cause onSuccess/onFailure to be called again.
Oh, I get it, ( but the MQTTAsync_reconnect doc don't mention that it only used by automatic reconnect), i will try it and post the result later, thank you.
linxy.
Reconnect() can be used outside of automatic reconnect, but that was the main reason for it. Outside automatic reconnect, it is like a connect(), but there are no onSuccess/onFailure callbacks - just connected(). If you want onSuccess/onFailure again, use connect().
I think this is resolved.
Thank you. yes, it's resolved, after few days automatic tests, this problem never appeared.
linxy.
Hi i met the problem that reconnect callback is not triggered, detail describe as follow.
env:
scene:
do step 3 to step 8 few times, i found that the reconnect callback is not triggered.
the reconnect code:
the connect relative callbacks.
for this test, the down side is the call tarce, we call reconnect 4 times. the upper side is the callback log, the first three times are all triggerd but the 4th time not.
the first different point between the 3th log and the 4th log, SSLsocket error.
the 3th one full log.
the 4th one full log.
Thanks. linxy.