天天看点

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