問題:
Mosquitto用戶端被服務端斷開之後,MQTT用戶端connect失敗
分析:
MQTT的主題訂閱是通過connet成功之後調用的回調函數内部處理,
//2. 設定回調用戶端
mosquitto_connect_callback_set(m_pSubHandle, MosqMqttConnect);
//描述:連接配接的回調函數
void MosqMqttConnect(struct mosquitto* mosq, void* userdata, int result)
{
CMosqSrv *pCMosqSrv = (CMosqSrv*)userdata;
if (pCMosqSrv != nullptr)
{
DTRACE(L_DETAIL, DB_MQTT_BASE, "%s: ClientID=%s, rc=%d, Result=%s\n", __FUNCTION__, pCMosqSrv->GetClientID(mosq).c_str(), result, mosquitto_strerror(result));
if (result == MOSQ_ERR_SUCCESS)
{
if (pCMosqSrv->GetSubHandle() == mosq)
pCMosqSrv->SubTopic(mosq);
}
}
}
//描述:訂閱主題
bool CMosqSrv::SubTopic(struct mosquitto* mosq)
{
for (WORD wIdx = 0; wIdx < m_wTopNum; wIdx++)
{
int iRet = mosquitto_subscribe(mosq, NULL, m_pTopCfg[wIdx].sTopic.c_str(), m_pTopCfg[wIdx].iQOS);
if (iRet == MOSQ_ERR_ERRNO)
{
DTRACE(L_DETAIL, DB_MQTT_BASE, "%s: Subscribe fail: topic=%s, QOS%d\n", __FUNCTION__, m_pTopCfg[wIdx].sTopic.c_str(), m_pTopCfg[wIdx].iQOS);
return false;
}
else
{
DTRACE(L_DETAIL, DB_MQTT_BASE, "%s: Subscribe succ: topic=%s, QOS%d\n", __FUNCTION__, m_pTopCfg[wIdx].sTopic.c_str(), m_pTopCfg[wIdx].iQOS);
}
}
return true;
}
但是出現了一種情況,就是MQTT的連接配接交由MQTT的用戶端庫處理時,它隻會嘗試一次連接配接,而恰好這次連接配接失敗了,導緻沒有在處理。
連接配接失敗的封包
[ 2020/12/06 07:27:36 ] MosqMqttLog: Client ccoRouterPub2 sending PINGREQ
[ 2020/12/06 07:27:36 ] MosqMqttLog: Client ccoRouterPub2 received PINGRESP
[ 2020/12/06 07:28:08 ] MosqMqttDisconnect: ClientID=ccoRouterSub1, rc=7, Result=The connection was lost.
[ 2020/12/06 07:28:09 ] MosqMqttLog: Client ccoRouterSub1 sending CONNECT
[ 2020/12/06 07:28:36 ] MosqMqttLog: Client ccoRouterPub2 sending PINGREQ
[ 2020/12/06 07:28:36 ] MosqMqttLog: Client ccoRouterPub2 received PINGRESP
[ 2020/12/06 07:29:36 ] MosqMqttLog: Client ccoRouterPub2 sending PINGREQ
[ 2020/12/06 07:29:36 ] MosqMqttLog: Client ccoRouterPub2 received PINGRESP
連接配接成功的封包:
[ 2020/12/06 06:34:41 ] MosqMqttDisconnect: ClientID=ccoRouterSub1, rc=7, Result=The connection was lost.
[ 2020/12/06 06:34:42 ] MosqMqttLog: Client ccoRouterSub1 sending CONNECT
[ 2020/12/06 06:34:42 ] MosqMqttLog: Client ccoRouterSub1 received CONNACK
[ 2020/12/06 06:34:42 ] MosqMqttConnect: ClientID=ccoRouterSub1, rc=0, Result=No error.
[ 2020/12/06 06:34:42 ] MosqMqttLog: Client ccoRouterSub1 sending SUBSCRIBE (Mid: 926, Topic: +/get/request/ccoRouter/masterNode, QoS: 0)
[ 2020/12/06 06:34:42 ] SubTopic: Subscribe succ: topic=+/get/request/ccoRouter/masterNode, QOS0
兩者之間的差别是一個隻有“CONNECT”,另外一個是“CONNECT、CONNACK”。