You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:15:51