问题:
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”。