带有esp32的AWS iot接收来自某些主题的消息,但不接收其他主题的消息吗?

时间:2020-01-05 01:45:22

标签: c++ c iot aws-iot esp32

我正在使用this aws-iot library for esp32,但在接收来自某个主题的消息时遇到问题。

我的代码:

if (device.connect(HOST_ADDRESS, const_cast<char*>(client_id.c_str())) == 0) {
    Serial.println("Connected To AWS");
    delay(1000);

    char getAcceptedTopic[60];
    strcpy(getAcceptedTopic, "Lamps/"); //these ones need to be strcpy to get it started
    strcat(getAcceptedTopic, const_cast<char*>(myLampCred.username.c_str()));
    strcat(getAcceptedTopic, "/rga");

    Serial.print("\ngetAcceptedTopic: ");
    Serial.print(getAcceptedTopic);


    char republishedShadowTopic[60];
    strcpy(republishedShadowTopic, "Lamp/");
    strcat(republishedShadowTopic, const_cast<char*>(myLampCred.username.c_str()));
    strcat(republishedShadowTopic, "/rs");



    if (0==device.subscribe(getAcceptedTopic, mySubCallBackHandler)) {
    //if (0==device.subscribe("Lamps/SamHang/rs", mySubCallBackHandler)) { //try just doing it with the string? 
    Serial.print("Subscribe Successful");
    } else {
    Serial.println("Subscribe Failed, Check The Thing Name and Certificates");
    while(1);
    } 

    if (0==device.subscribe("testchannel", mySubCallBackHandler)) {
    Serial.println("Subscribe Successful");
    } else {
    Serial.println("Subscribe Failed, Check The Thing Name and Certificates");
    while(1);
    } 
    //will need to add in effects/channel topic at some point, but since none of the effects code is set up yet anyways, theres no point in adding a topic now

    Serial.println(republishedShadowTopic);
    if (0 == device.subscribe(republishedShadowTopic, mySubCallBackHandler)){
        Serial.println("Subscribe Successful");
    } else {
        Serial.println("Subscribe Failed, Check The THing Name and Certificates");
        while(1);
    }

    delay(500);
    //send get request
    gettingShadow = true;
    std::string shadowGetTopic = "$aws/things/" + myLampCred.username + "Lamp/shadow/get";
    publishFunc(shadowGetTopic.c_str(), "");
} else {
    //could add error for this but unless the host address changes and EVERYTHING breaks or wifi isn't connected, then there shouldn't be a problem
    Serial.println("AWS connection failed, check the HOST address");
    while(1);
}

我订阅了三个主题,分别是testchannel,Lamps / user / rga(在变量getAcceptedTopic中)和Lamp / user / rs(在变量republishedShadowTopic中)。

在这些主题中,用户可以根据将代码上传到哪个设备以及使用myLampCred.username(返回std :: string)检索用户名的方式进行更改。因此,如果myLampCred.username = actualUsername,则应订阅的getAccepted主题名称是“ Lamps / actualUsername / rga”

我能够始终在我的getAccepted主题和testchannel主题上接收消息,但不会在republishedShadow主题上接收消息。如果我将republishedShadowTopic变量替换为“ Lamp / actualUsername / rs”,则它可以正常工作并收到应有的消息。我认为问题与我如何声明/构建变量有关,但是我以相同的方式使getAccepted主题变量正常运行吗?

我还通过每个主题发送了不同长度的消息,并且每个消息相对于其主题都得到相同的结果,因此我认为这与消息的内容无关。 我还检查了配置文件,我认为没有什么会限制它吗? 我很确定任何问题都在我共享的代码段中,因为收到的任何消息都会在到达时宣布。

我目前的理论是某处存在数据类型问题?但是device.subscribe()方法正在请求一个char *,据​​我所知,这就是我给的(我对所有char []与char *和const的了解仍然不是100% 每个是什么,但我想不是如何使用它们)。我尝试了各种形式的chars和std :: string转换,但是除非基于字符串文字,否则似乎没有任何作用。

对此我感到非常困惑,任何帮助将不胜感激,谢谢! :D

1 个答案:

答案 0 :(得分:1)

创建republishedShadowTopic的代码看起来不错。此代码创建的字符串应该与字符串文字"Lamp/actualUsername/rs"相同,只是看起来here

我不是Arduino方面的专家,但据我所知,字符串文字可能存储在只读存储器中(我想如果是Arduino,那将是闪存)。

尝试修改字符串文字结果是未定义的行为:它们可能存储在只读存储区(例如.rodata)中,或者与其他字符串文字结合在一起。

使用字符串文字时它起作用的原因可能是它的静态存储持续时间。

字符串文字具有静态的存储期限,因此在程序生命周期内存在内存中。

另一方面,您的数组具有自动存储期限,这意味着退出当前范围后,它可能无效。

看看here时,您会看到字符串的地址已经转发并存储了right here

在此if语句中退出作用域之后:

if (device.connect(HOST_ADDRESS, const_cast<char*>(client_id.c_str())) == 0)

您不能再依赖此指针。我假设您退出该if语句后会收到一条消息。

您可以很容易地检验我的假设。只需将此数组设置为静态或全局数组,然后检查其是否有效。您应该对第一个数组执行相同的操作,因为您可能很幸运它起作用了。

相关问题