使用Mosquitto C连接AWS时OnConnect回调未触发且连接丢失(错误码7)
Mosquitto C库连接AWS IoT时onConnect回调未触发,连接丢失错误码7的排查方案
你这情况我之前也碰到过,确实挺挠头的:用Mosquitto C库向AWS IoT推送数据时,mosquitto_connect()函数明明返回成功,但onConnect()回调完全没触发,反而onDisconnect()回调抛出了错误码7(对应MOSQ_ERR_CONN_LOST),而且之前程序运行一切正常,突然就出了这问题。
先贴出你提供的相关代码片段:
static void onDisconnect(struct mosquitto *mosq, void *obj, int rc){ std::cout<<__FUNCTION__<<" : "<<__LINE__<<" : "<<mosquitto_strerror(rc)<<std::endl; cout << "disconnect status..." << rc << endl; // mosquitto_loop_stop(mosq, false); (void)obj, (void)mosq; } static void onConnect(struct mosquitto *mosq, void *userdata, int result){ std::cout<<__FUNCTION__<<" : "<<__LINE__<<" : mosquitto connect callback succeed. \n "<<std::endl; } static void onCallback(struct mosquitto *mosq, void *userdata, int level, const char *str){ // Print all log messages regardless of level. (void)mosq, (void)userdata, (void)level; std::cout<<__FUNCTION__<<" : "<<str<<std::endl; } mosquitto_lib_init(); struct mosquitto * mosq = NULL; const char *clientId = "ClientId"; mosq = mosquitto_new(clientId, true, NULL); if (!mosq) { std::cout<<__FUNCTION__<<" : "<<__LINE__<<" mosquitto_new failed. \n "<<std::endl; return; }else std::cout<<__FUNCTION__<<" : "<<__LINE__<<" mosquitto_new succeed. \n "<<std::endl; mosquitto_tls_opts_set(mosq, 1, NULL, NULL); mosquitto_tls_set(mosq, "/etc/ssl/certs/ca-certificates.crt", NULL, "/opt/usr_data/tests/LoaderPoc/certs/cert.pem", "/opt/usr_data/tests/LoaderPoc/certs/privkey.pem", NULL); mosquitto_connect_callback_set(mosq, onConnect); mosquitto_disconnect_callback_set(mosq, onDisconnect); mosquitto_log_callback_set(mosq, onCallback); //mosquitto_publish_callback_set(mosq, onPublish); const char *host = "a2eg3przjv23yh.iot.us-east-1.amazonaws.com"; auto ret = mosquitto_connect(mosq, host, 8883, 60); cout << "connection status.." << ret <<endl; auto loop_ret = mosquitto_loop_start(mosq); cout << "Loop status..." << loop_ret << endl;
运行时的输出如下:
MachineAppOnBoardManager::onCallback : Client ClientId sending CONNECT
MachineAppOnBoardManager::onDisconnect : 160 : The connection was lost.
disconnect status...7
一步步排查问题的方向
1. 先查TLS证书环节(最常见的原因)
AWS IoT对证书的有效性要求非常严格,哪怕证书过期、被撤销,或者CA证书不对,都会出现“连接发送后直接丢失”的情况:
- 登录AWS IoT控制台,检查你的
cert.pem对应的证书状态是不是ACTIVE,有没有被标记为撤销或过期 - 替换系统默认的CA证书为AWS官方的根CA(比如Amazon Root CA 1),系统默认的
/etc/ssl/certs/ca-certificates.crt可能没包含AWS的根CA,导致TLS握手失败 - 用openssl手动验证证书链是否正常:
如果这个命令执行失败,那就是证书的问题,先把证书环节搞定。openssl s_client -connect a2eg3przjv23yh.iot.us-east-1.amazonaws.com:8883 -cert /opt/usr_data/tests/LoaderPoc/certs/cert.pem -key /opt/usr_data/tests/LoaderPoc/certs/privkey.pem -CAfile AmazonRootCA1.pem
2. 检查AWS IoT策略是否允许这个客户端连接
- 确认你的AWS IoT策略里,有没有允许
ClientId进行iot:Connect操作,策略需要包含类似这样的语句:
测试阶段可以用通配符{ "Effect": "Allow", "Action": "iot:Connect", "Resource": "arn:aws:iot:us-east-1:你的AWS账号ID:client/ClientId" }*暂时允许所有客户端连接,排除策略的问题。
3. 确认Mosquitto循环线程的运行状态
你调用了mosquitto_loop_start()开启后台循环线程,但要注意:
- 确保主线程没有过早退出!如果主线程在调用
mosquitto_loop_start()之后直接结束,后台循环线程也会被终止,导致连接刚建立就丢失。可以在主线程加个while(true)或者等待信号(比如pause()),保持程序运行 - 检查
mosquitto_loop_start()的返回值loop_ret是不是0,如果非0说明循环线程启动失败,这也会导致连接无法维持
4. 网络连通性与端口检查
- 测试设备能不能访问AWS IoT端点:用
telnet a2eg3przjv23yh.iot.us-east-1.amazonaws.com 8883看看能不能建立连接,如果连不上,检查防火墙、安全组是不是拦截了8883端口的出站流量 - 确认设备的DNS解析正常,能正确解析AWS IoT的域名
5. 开启详细日志定位细节
你的onCallback回调已经打印日志,但可以把日志级别调到DEBUG,获取更详细的连接过程:
mosquitto_set_log_level(mosq, MOSQ_LOG_DEBUG); // 在设置日志回调之后加上这句
这样能看到TLS握手的每一步,以及AWS返回的具体错误信息,帮你精准定位问题。
6. 排查Mosquitto版本兼容性
如果最近升级了Mosquitto库,可能存在API行为变化。可以尝试回退到之前能正常运行的版本,或者查看Mosquitto的release notes,确认连接回调相关的逻辑有没有变更。
内容的提问来源于stack exchange,提问作者chinmaya
相关产品推荐
相关产品推荐

