天天看點

Mosquitto connect連接配接失敗

問題:

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”。

繼續閱讀