This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CC3235SF:服务器断开连接后尝试重新连接 RabbitMQ 时出现 API 错误

Guru**** 2556920 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/wi-fi-group/wifi/f/wi-fi-forum/1130084/cc3235sf-api-error-when-trying-to-reconnect-to-rabbitmq-after-server-disconnect

器件型号:CC3235SF

当我在服务器断开连接后尝试重新连接 MQTT 时、返回-2005错误。

void ics_mqtt_connect_timer(sigval val)
{
    /* Clear the timer interrupt. */
    Platform_TimerInterruptClear();
    if (mqtt_connect_pending)
    {
        mqtt_connect_timer_cntr++;
        mqtt_connect_pending = 0;
    }
}

void ics_mqtt_process()
{
   // Handle reconnect of the MQTT process.
static uint8_t prevConnected = 0;
int32_t ret = 0;

    if (deviceConnected)
    {
        if (mqtt_connect_pending == 0)
        {
            if (prevConnected)
            {
                ret = MQTT_IF_Disconnect(globalmqttClientHandle);
                ret = MQTT_IF_Deinit(globalmqttClientHandle);
            }
            ret = MQTT_IF_Init(mqttInitParams);
            if (ret >= 0)
            {

                char subscribeTopic[64];
                ics_mqtt_build_topic(subscribeTopic, MQTT_SUB_TOPIC_NAME_SERVER);
                ret = MQTT_IF_Subscribe(globalmqttClientHandle, subscribeTopic, MQTT_QOS_2, ics_mqtt_server_events_callback);
                globalmqttClientHandle = MQTT_IF_Connect(mqttClientParams, mqttConnParams, MQTT_EventCallback);
                mqtt_connect_pending = 1;
                prevConnected = 1;
                // set one minute timeout for retries.
                Platform_TimerStart(180000, gMqttTimer, 0);
            }
        }
    }
    usleep(10000);
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    -2005是 sl_api_aborted、如果它总是发生、你可以尝试放置一个断点并尝试捕捉中断的确切原因。

    如果  ICS_MQTT_Process 是从 Disconnect 上下文中调用的、则可以尝试使用回调上下文中的信号对象、并从另一个线程上下文中执行(重新)连接(如果我没有弄错的话、就像在示例应用中完成的那样)...

    是否在 SDK 的参考 MQTT_CLIENT 示例中重现此问题?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    该循环发生在线程中。

    很抱歉、我在 p 中的代码中犯了一个错误

    void MQTT_EventCallback(int32_t event){
    
        uint32_t retc = 0;
        switch(event){
    
            case MQTT_EVENT_CONNACK:
            {
                ics_mqtt_connected = 1;
                mqtt_connect_pending = 0;
    //            LOG_INFO("MQTT_EVENT_CONNACK\r\n");
                break;
            }
    
            case MQTT_EVENT_SUBACK:
            {
                ics_mqtt_subscribed = 1;
    //            LOG_INFO("MQTT_EVENT_SUBACK\r\n");
                break;
            }
    
            case MQTT_EVENT_PUBACK:
            {
    //            LOG_INFO("MQTT_EVENT_PUBACK\r\n");
                break;
            }
    
            case MQTT_EVENT_UNSUBACK:
            {
    //            LOG_INFO("MQTT_EVENT_UNSUBACK\r\n");
                break;
            }
    
            case MQTT_EVENT_CLIENT_DISCONNECT:
            {
                ics_mqtt_connected = 0;
                ics_mqtt_subscribed = 0;
                mqtt_connect_pending = 0;
    //            LOG_INFO("MQTT_EVENT_CLIENT_DISCONNECT\r\n");
                if(deinit == 0){
    
                }
                set_last_transmitted_sector();
                break;
            }
    
            case MQTT_EVENT_SERVER_DISCONNECT:
            {
                //            LOG_INFO("MQTT_EVENT_SERVER_DISCONNECT\r\n");
                if (ics_mqtt_connected)
                {
                    retc = MQTT_IF_Disconnect(globalmqttClientHandle);
                    retc = MQTT_IF_Deinit(globalmqttClientHandle);
                    ics_mqtt_server_disconnect = 1;
                }
                ics_mqtt_connected = 0;
                ics_mqtt_subscribed = 0;
                mqtt_connect_pending = 0;
                break;
            }
    
            case MQTT_EVENT_DESTROY:
            {
    //            LOG_INFO("MQTT_EVENT_DESTROY\r\n");
                break;
            }
        }
    }
    
    
    void ics_mqtt_process()
    {
       // Handle reconnect of the MQTT process.
    int32_t ret = 0;
    
        if (ics_wifi_connected && ics_wifi_ip_acquired)
        {
            if (ics_mqtt_connected)
            {
                // do stuff
            }
            else
            {
                if (mqtt_connect_pending == 0)
                {
                    ret = MQTT_IF_Init(mqttInitParams);
                    if (ret >= 0)
                    {
    
                        char subscribeTopic[64];
                        ics_mqtt_build_topic(subscribeTopic, MQTT_SUB_TOPIC_NAME_SERVER);
                        ret = MQTT_IF_Subscribe(globalmqttClientHandle, subscribeTopic, MQTT_QOS_2, ics_mqtt_server_events_callback);
                        globalmqttClientHandle = MQTT_IF_Connect(mqttClientParams, mqttConnParams, MQTT_EventCallback);
                        mqtt_connect_pending = 1;
                        // set one minute timeout for retries.
                        Platform_TimerStart(180000, gMqttTimer, 0);
                    }
                    else
                    {
                        ret = MQTT_IF_Deinit(globalmqttClientHandle);
                    }
                }
            }
        }
        usleep(10000);
    }
    
    
    void *icsMqttMainThread(void *arg0)
    {
        int32_t ret;
    
        ret = ti_net_SlNet_initConfig();
        if(0 != ret)
        {
            while(1);
            //LOG_ERROR("Failed to initialize SlNetSock\n\r");
        }
    
        ret = WifiInit();
        if(ret < 0){
            while(1);
        }
    
        // Init MQTT Connect / Regsiter Ten Second Timer.
        Platform_TimerInit(ics_mqtt_connect_timer, &gMqttTimer);
    
        while(1)
        {
            ics_mqtt_process();
        }
    
    }
    
    在此处进行处理。

    缺少 IF。  我还添加了一些进一步的内容。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    此外、发生这种情况时、也不会设置断点。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您可以在 MQTT_CONNECT 中添加断点(假设该 API 返回 API_ABORT)。 如果在服务器断开连接后出现问题、则可以跳过第一个断点。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我现在正在努力了解这一细节。  我无法使用该示例测试此情况、因为在这种情况下、服务器似乎实际上不是断开连接的原因。  它似乎来自 API 本身。  我可能正在流式传输大量消息1Mbit 流。  大约30分钟后、我得到该错误。

    此外、MQTT_IF_Init 似乎无法使其恢复到初始化状态、即使之前是 deinit 也是如此。  这两个函数从 MQTT 客户端演示中提取。  是否缺少某些步骤?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我们需要更好地了解断开连接的原因。

    MQTT_IF_Init 应在 MQTT_IF_DEINIT 之后工作-请检查函数内到底发生了什么故障(包括错误代码)。

    MQTT_IF_DEINIT 是否返回 OK (0)?

    您是否已关闭连接(MQTT_IF_Disconnect 返回正常?) 调用 deinit 之前?

      

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Kobi、

    我在 client_core.c 中捕获了重新连接至此点时的错误

    静态 Int32_t connectMsgSend (MQTT_ClientCtx_t * clCtx、bool cleanSession、uint16_t kaSecs)

    MQTT_Packet_t * mqp = MQTTClientCore_allocSend (MQTT_connect);
    uint8_t *buf、*ref、conn_opts = cleanSession? MQTT_CONN_MSG_FLAG_CLEAR_START:0;
    int32_t RV = MQTT_packet_ERR_PKT_LEN;
    uint32_t fsz;/*在 PKT 中可用缓冲区大小*/
    uint16_t VHL = getConnectVhLen (clCtx);

    如果(NULL ==mqp)

    返回 MQTT_PACKE_ERR_PKT_AVL;

    它返回这里。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    似乎是内存问题。 您能否在尝试重新连接之前添加一些延迟? (让内核线程释放缓冲区-假设延迟不 会阻止 MQTT 内核线程)。

    另一个选项是添加可用于 MQTT 的数据包数量(默认情况下定义为2、请参阅 source/ti/net/MQTT/interface/mqttclient.c 中的 MQTTCLIENT_MAX_MQP)。有关编译库的指令、请参阅 /docs/simplelink_mcu_sdk/Quick_Start_Guide.html