认识MQTT协议

2024-03-07 14:10:38 浏览数 (2)

Hi,大家好!今天我们来认识一下物联网通信中重要的通信协议MQTT。

unsetunset1、MQTT是什么unsetunset

MQTT(Message Queuing Telemetry Transport)是一种轻量级的消息协议,设计用于在低带宽、不稳定或高延迟的网络环境中传输消息。MQTT最初由IBM开发,后来成为OASIS标准,广泛用于物联网(IoT)应用和其他需要高效消息传递的场景。

MQTT是轻量级基于代理的发布/订阅的消息传输协议,它可以通过很少的代码和带宽和远程设备连接。例如通过卫星和代理连接,通过拨号和医疗保健提供者连接,以及在一些自动化或小型设备上,而且由于小巧,省电,协议开销小和能高效的向一和多个接收者传递信息,故同样适用于移动应用设备上。

  • 早在1999年,IBM的Andy Stanford-Clark博士以及Arcom公司ArlenNipper博士发明了MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)技术 。
  • MQTT的话题是他们在谈论开源物联网平台Pachube时提到的。Stanford-Clark认为Pachube很酷,其不足之处是不具备真正的推送功能。你需要不断的进行轮询才能得到即时数据。这正是MQTT能够实现的,他提到了使用推送通信系统的石油管道检测系统。

unsetunset2、MQTT协议的关键概念和特性unsetunset

以下是MQTT协议的一些关键概念和特性:

1. 发布/订阅模型:

MQTT采用发布/订阅模型,消息的发送者称为发布者(Publisher),而消息的接收者称为订阅者(Subscriber)。发布者将消息发布到主题(Topic),而订阅者可以选择订阅特定主题以接收相关消息。

2. 主题(Topic):

主题是MQTT中消息的分类标识,用于将消息发送到特定的目标。订阅者可以通过订阅特定主题来接收与该主题相关的消息。主题可以是层次结构的,例如:home/living-room/temperature,其中home是根主题,living-roomhome的子主题,temperatureliving-room的子主题。

3. 消息质量等级(QoS):

MQTT支持不同的消息质量等级,用于确保消息传递的可靠性。共有三个等级:

  • QoS 0: 最多一次传递,消息可能会丢失或重复。
  • QoS 1: 至少一次传递,确保消息至少被接收一次。
  • QoS 2: 刚好一次传递,确保消息仅被接收一次。

4. 保留消息:

发布者可以发送保留消息,这是一个持久的消息,当有新订阅者订阅与保留消息相匹配的主题时,将立即发送该消息。这对于传递重要信息或者初始化状态很有用。

5. 遗嘱消息(Will Message):

连接到MQTT代理的客户端可以指定一个遗嘱消息。如果客户端非正常断开连接,代理将自动发布遗嘱消息到预定的主题。这可用于通知其他客户端某个设备的状态变化。

6. 保持活动性(Keep Alive):

MQTT使用保持活动性机制来确保客户端与代理之间的连接保持活动。客户端会定期向代理发送保持活动性的消息,如果代理在指定的时间内未收到客户端的消息,将关闭连接。

7. 连接过程:

MQTT的连接过程包括客户端向代理发送连接请求、代理响应并确认连接、客户端发送连接信息、代理确认连接信息。在这个过程中,客户端和代理之间会协商使用的MQTT版本、连接的用户名和密码、保持活动性时间等。

8. 安全性:

MQTT本身并没有内建的安全性机制,但可以通过TLS/SSL进行加密传输。此外,可以通过用户名和密码进行身份验证,以及通过访问控制列表(ACL)限制客户端的访问权限。

unsetunset3、MQTT客户端代码示例unsetunset

实现一个完整的MQTT协议是一个庞大而复杂的任务,因为MQTT涉及到多个方面,包括连接、发布/订阅、消息质量等级等。下面是一个简化的C 实现的示例,用于建立一个基本的MQTT客户端,演示连接到MQTT代理服务去发布/订阅消息。

该示例使用了 Eclipse Paho MQTT C 客户端库,该库提供了MQTT协议的C 实现。有兴趣的小获取可以去官网了解一下。

首先,确保你已经安装了 Paho MQTT C 客户端库。可以从Paho官网获取该库。

接下来,以下是一个简单的C 示例:

代码语言:javascript复制
#include <iostream>
#include <mqtt/async_client.h>

class MQTTCallbacks : public virtual mqtt::callback, public virtual mqtt::iaction_listener {
    void connectionLost(const std::string& cause) override {
        std::cout << "Connection lost: " << cause << std::endl;
    }

    void deliveryComplete(mqtt::delivery_token_ptr tok) override {
        std::cout << "Message delivered" << std::endl;
    }

    void onSuccess(const mqtt::token& tok) override {
        std::cout << "Action successful" << std::endl;
    }

    void onFailure(const mqtt::token& tok) override {
        std::cout << "Action failed" << std::endl;
    }
};

int main() {
    const std::string brokerAddress = "tcp://localhost:1883";
    const std::string clientId = "cpp_mqtt_client";
    const std::string topic = "test/topic";

    mqtt::async_client client(brokerAddress, clientId);

    MQTTCallbacks callbacks;
    client.set_callback(callbacks);

    mqtt::connect_options connOpts;
    connOpts.set_keep_alive_interval(20);
    connOpts.set_clean_session(true);

    try {
        std::cout << "Connecting to the broker..." << std::endl;
        client.connect(connOpts)->wait();
        std::cout << "Connected!" << std::endl;

        std::string payload = "Hello, MQTT!";
        mqtt::message_ptr pubmsg = mqtt::make_message(topic, payload);
        pubmsg->set_qos(1);
        client.publish(pubmsg)->wait();

        std::cout << "Message published" << std::endl;

        client.subscribe(topic, 1)->wait();

        while (true) {
            // Continue to keep the program running
            std::this_thread::sleep_for(std::chrono::seconds(1));
        }

        client.unsubscribe(topic)->wait();
        client.disconnect()->wait();
    } catch (const mqtt::exception& exc) {
        std::cerr << "Error: " << exc.what() << std::endl;
        return 1;
    }

    return 0;
}

该示例假定了本地运行的MQTT代理地址为 tcp://localhost:1883,客户端连接后发布了一条消息到主题 test/topic,并订阅了该主题。实际开发中我们需要修改 brokerAddress 和其他参数。

需要说明的是这只是一个简单的示例,实际上MQTT的实现要更加复杂,需要处理连接丢失、重连、消息质量等级等情况。在实际应用中,建议使用现成的MQTT客户端库,以确保正确性和稳定性。

unsetunset小结unsetunset

MQTT在实际开发中需要学习的内容有很多,而且很多细节需要注意。希望正在学习MQTT协议的小伙伴通过本节内容对MQTT协议有个初步的认识。

题外话:学习技术是一个慢慢沉淀的过程。不积跬步无以至千里,技术同样如此。希望小伙伴们在以后的技术路上坚持下去,并到达一片开阔的境地。

0 人点赞