首页 > 解决方案 > 计算消息从服务器到达的时间(mqtt)

问题描述

我有一个订阅发布者的 mqtt 客户端。我使用了这里的示例代码。

消息不定期发布(不是定期发布)。我想在消息到达时启动一个计时器,这样如果“X”秒过去了,我就可以调用另一个函数。有人可以建议我如何做到这一点(一个例子真的很有帮助)。

class callback : public virtual mqtt::callback, public virtual mqtt::iaction_listener
    {
        void message_arrived(mqtt::const_message_ptr msg) override
        {
            std::cout << "Message arrived" << std::endl;
            timerStart = std::chrono::system_clock::now();
        }

    public:
        callback(mqtt::async_client& cli, mqtt::connect_options& connOpts, std::string topic)
            : nretry_(0), cli_(cli), connOpts_(connOpts), subListener_("Subscription"), TOPIC(topic)
        {
            tEth = std::thread(&callback::checkTimeBwMsgs, this);
        }
    
        double getElapsedTimeBwMsgs()
        {
            auto t_now = std::chrono::system_clock::now();
            elapsed_time_ms = std::chrono::duration<double, std::milli>(t_now - timerStart).count();
            
            return elapsed_time_ms;
        }
    
        bool getIsData()
        {
            return isData;
        }
    
        void checkTimeBwMsgs()
        {
            double timeDur = getElapsedTimeBwMsgs();
            std::cout << timeDur << std::endl;
            if(timeDur > 1000.0)
                // do something
        }
    
        ~callback()
        {
            tEth.join();
        }
    };

当客户端收到来自代理/发布者的消息时,会调用方法“message_arrived”。我在构造函数中创建了一个 std::thread ,它应该能够测量 2 条消息之间经过的时间,如果经过的时间大于 5 秒,则调用另一个方法。

此方法只计算一次经过的时间。只要程序正在运行,我就希望它这样做。我不确定我的方法是否正确。

mqtt paho 库中是否有任何方法可以在收到消息后给出经过的时间,无论何时需要。

方法二:

int main()
{
    mqtt::async_client client(SERVER_ADDRESS, CLIENT_ID);
    mqtt::connect_options connOpts;
    connOpts.set_keep_alive_interval(5);
    connOpts.set_clean_session(true);

    callback cb(client, connOpts, TOPIC);
    client.set_callback(cb);
    
    std::thread tEth(ThreadFunc, cb);
}

在这里,我在主函数中创建一个线程,并将回调类的对象作为参数传递。这给出了以下错误:

在此处输入图像描述

在方法 2 中,我的想法是将类对象作为参数传递。在类中,创建一个成员变量,用于保存收到最后一条消息的时间。在上面的线程中,我将通过类对象调用成员变量来不断检查经过的时间。

标签: c++mqttpaho

解决方案


根据您的评论,听起来 MQTT 的Keep Alive机制就是您所追求的。无论您使用什么经纪人,都会以一种或另一种方式实现这一点。

在 CONNECT 上,您的客户端可以以秒为单位指定 Keep Alive 时间。在你的情况下,10 秒。该值是来自客户端和服务器的消息之间可以传递的最长时间。根据规范:

客户端有责任确保发送 MQTT 控制数据包之间的时间间隔不超过 Keep Alive 值。如果 Keep Alive 非零且没有发送任何其他 MQTT 控制数据包,则客户端必须发送 PINGREQ 数据包

这意味着,不是您的客户端手动检查服务器连接是否处于活动状态,而是指定此值应该让客户端库通过定期 ping 服务器来处理此问题。


推荐阅读