-2

Using RapidJSON, I can read a local json file by:

std::ifstream ifs { R"(/home//am_v2.json)" };
IStreamWrapper isw { ifs };
Document doc {};
doc.ParseStream( isw );

However, I want to read a variable received from:

auto msg = mqttClient->consume_message();

The content is shown by msg->to.string()

However, I cannot get this content to be read using:

std::ifstream ifs { msg }; 

Any clue?

Here a more complete code:

void MqttApplication::send()
{
    
    try {
        
        mqttClient->start_consuming();
        mqttClient->subscribe(TOPIC, QOS)->wait();        
    }
    catch (const mqtt::exception& exc) {
        cerr << exc.what() << endl;
        return;
    }
    
    while (true) {
        auto msg = mqttClient->consume_message();
        

        if (!msg) {
            if (!mqttClient->is_connected()) {
                cout << "MQTT: mqtt_application lost connection. Attempting reconnect" << endl;
                if (mqttTryReconnect(*mqttClient)) {
                    mqttClient->subscribe(TOPIC, QOS);
                    cout << "MQTT: mqtt_application reconnected" << endl;
                    continue;
                }
                else {
                    cout << "MQTT: mqtt_application reconnect failed." << endl;
                }
            }
            else {
                cout << "MQTT: mqtt_application an error occurred retrieving messages." << endl;
            }
            break;
        }
        

        if (msg->get_topic() == "command" &&
                msg->to_string() == "exit") {
            cout << "Exit command received" << endl;
            break;
        }
        
        cout << msg->get_topic() << ": " << msg->to_string() << endl;
        Document doc;
        doc.Parse(msg->to.string());
    }
}

Thanks

thecoder
  • 7
  • 3
  • 3
    Please do your homework before asking on StackOverflow, I found the documentation for `Document::Parse(const std::string&)` in two minutes. You may need to `#define RAPIDJSON_HAS_STDSTRING 1` first. – Botje Oct 26 '20 at 12:07
  • I've done my homework, have you seen the code above? I already said I can open a local json file, however, I cannot read a recieved message`#define RAPIDJSON_HAS_STDSTRING 1` is already defined in rapidjson.h, Still, using the code you've provided me, doesn't work – thecoder Oct 26 '20 at 14:52
  • 1
    You did not do your homework, you're trying to pass your message as a filename to the ifstream constructor. To me that sounds like mindlessly adapting the first code sample you found. I did two minutes of searching and found a function in the rapidjson documentation that directly takes a json string to parse. Show us how you tried to use that function and any errors you get, compile or otherwise. – Botje Oct 26 '20 at 15:06
  • As usual, a [mcve] should be provided. I also guess that you would have come found yourself that a file name and the content of a file are two different things, even if both are represented by something string-like. As a new user, please take the [tour] and read [ask]. – Ulrich Eckhardt Oct 26 '20 at 16:50

1 Answers1

0

First, make sure you

#define RAPIDJSON_HAS_STDSTRING 1

before you include the Rapidjson headers.

Parsing the contents of a message from mqtt is then as simple as:

Document doc;
doc.Parse(msg->to.string());
Botje
  • 26,269
  • 3
  • 31
  • 41
  • I get this error `error: ‘msg’ was not declared in this scope` – thecoder Oct 26 '20 at 15:55
  • I thought you received your mqtt message into a `msg` variable? It's right there in your question text! – Botje Oct 26 '20 at 15:57
  • @thecoder where do you show your message with `msg->to.string()` and where are you trying to parse the Json? Are they both in the same function? Are they in the same function where you say `auto msg = mqttClient->consume_message();`? Is your `msg` definition inside an `if` or another block and the `parse` is outside of it? We can't really help you more than this with just the code you are showing – John Doe Oct 26 '20 at 16:22
  • the mqtt message is consumed in msg variable, see above. Yes, all the code is within the same void function. – thecoder Oct 26 '20 at 16:25
  • can you post that function code? I did see what you posted and from that we can't tell what your problem is because they are just single lines without much context around them – John Doe Oct 26 '20 at 16:30
  • I just added it – thecoder Oct 26 '20 at 16:31
  • in your code you do `cout << msg->get_topic() << ": " << msg->to_string() << endl;` and then 2 lines after, and in your original question, you use `msg->to.string()` one of thos is probably incorrect (i'll throw out a guess and say that `to.string()` should be `to_string()`) – John Doe Oct 26 '20 at 16:37
  • Yes, it is `to_string()`. It compiles correctly, however, I cannot access the content of msg outside the while function. I've tried to declare msg at the header but still, doesn't print the content of msg. I know it is basic in programming but it is weird. – thecoder Oct 26 '20 at 20:11
  • Since you receive a different message with every iteration, isn't it logical that you can only access it inside the loop? – Botje Oct 26 '20 at 21:08
  • Yes, in the case the variable is declared inside the loop, makes sense it only is accessible inside, however, I've declared the variable at the top of the code as `const auto msg { " " };`, i guess like this, the msg should be accessible outside the while loop. – thecoder Oct 27 '20 at 08:31
  • No, because `auto msg =... ` declares a new variable. And if your top level `msg` is const you cannot assign to it. Also, don't you want to do something with *every* message that arrives instead of the last one in a (potentially) infinite loop? – Botje Oct 27 '20 at 08:40