一、MQTT介绍
MQTT ( Message Queuing Telemetry Transport , 消 息 队 列 遥 测 传 输 协 议 ), 是 一 种 基于发布/订 阅 publish/subscribe)模式的"轻量级"通讯协议,该协议构建于 TCP/IP 协议上,由 IBM 在 1999 年发布。MQTT 最大优点在于,可以以极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。作为一种低开销、低带宽占用的即时通讯协议,使其在物联网、小型设备、移动应用等方面有较广泛的应用。
MQTT 是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT 协议是轻量、简单、开放和易于实现的,
这些特点使它适用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。其在,通过卫星链路通信传感器、偶尔拨号的医疗设备、智能家居、及一些小型化设备中已广泛使用。
二、MQTT概念
2.1 订阅(Subscribtion)
订阅包含主题筛选器(Topic Filter)和最大服务质量(QoS)。订阅会与一个会话(Session)关联。一个会话可以包含多个订阅。每一个会话中的每个订阅都有一个不同的主题筛选器。
2.2 会话(Session)
每个客户端与服务器建立连接后就是一个会话,客户端和服务器之间有状态交互。会话存在于一个网络之间,也可能在客户端和服务器之间跨越多个连续的网络连接。
2.3 主题名(Topic Name)
连接到一个应用程序消息的标签,该标签与服务器的订阅相匹配。服务器会将消息发送给订阅所匹配标签的每个客户端。
需要注意的是,MQTT 中消息主题按照层级命名,使用 ‘/’ 进行分割
此外,主题中可以使用通配符进行多个主题或多层级的订阅,有两种常见的通配符:
1. 单层通配符 +:单层通配符只能匹配一层的主题,例如:China/Beijing/+,可以匹配的只有 Beijing 这个主 题下面一层的主题,例如 Xicheng, DongCheng, Xuanwu 等等。
2. 多层通配符 #:顾名思义,多层通配符就是可以匹配多个层级的主题,例如:China/#,可以匹配到的主题可能有:China/Beijing/Dongcheng, China/Shanghai/PuDong,等等。
2.4 主题筛选器(Topic Filter)
一个对主题名通配符筛选器,在订阅表达式中使用,表示订阅所匹配到的多个主题。
2.5 消息订阅
消息订阅者所具体接收的内容。
三、MQTT中的角色
1. Publisher 和 Subscriber 为客户端,Broker 为服务器端,消息主题为消息类型,Broker 根据 Topic 过滤消息,并将消息向客户端推送。
2. MQTT 中用 QoS 表示服务质量,MQTT 协议中有三种服务质量(QoS):
1) QoS =0,至多一次,可能会出现丢包的情况,使用在对实时性要求不高的情况,例如,将此服务质量与通信环境传感器数据一起使用。 对于是否丢失个别读取或是否稍后立即发布新的读取并不重要。
2) QoS =1,至少一次,保证包会到达目的地,但是可能出现重包。
3) QoS =2, 刚好一次,保证包会到达目的地,且不会出现重包的现象。
3.1 客户端
1. Publisher 和 Subscriber 都属于客户端。
2. 发布应用消息给其它相关的客户端。
3. 订阅以请求接受相关的应用消息。
4. 取消订阅以移除接受应用消息的请求。
5. 从服务端断开连接
3.2 服务器
1. 服务器端即所谓的 MQTT Broker 服务器。
2. 接受来自客户端的网络连接。
3. 接受客户端发布的应用消息。
4. 处理客户端的订阅和取消订阅请求。
5. 转发应用消息给符合条件的已订阅客户端。
6. MQTT 提供的公共服务器端(Broker)有:
1) test.mosquitto.org
2) broker.hivemq.com
3) iot.eclipse.org
四、X86平台安装mosquitto
4.1 下载 mosquitto 服务器
命令:
sudo apt-get install mosquitto
4.2 下载 mosquitto 客户端
sudo apt-get install mosquitto-clients
4.3 mosquitto 命令
4.3.1 mosquitto
启动服务器的命令,在 Ubuntu 里已经启动了。
4.3.2 mosquitto_pub
发布消息使用的命令
mosquitto_pub -h 192.168.0.137 -t "house" -m "500"
-h 是指定从哪个服务器发布
-t 是指定发布哪个主题
-m 是消息的内容
4.3.3 mosquitto_sub
订阅消息使用的命令
mosquitto_sub -h 192.168.0.137 -t "house" -v
-h 是指定从哪个服务器订阅;
-t 是指定订阅哪个主题;
-v 的意思是收到消息打印出来
五、软件测试
windows 安装 mqttfx-1.7.1-windows-x64.exe 测试软件并打开
测试结果:
六、QT使用MQTT
6.1 MQTT初始化
6.1.1 源码下载
使用这个库 Qt 版本必须大于 5.3,它有两个版本: master 和 release 版本,我们在此用 release 版本
6.2.1 将源码添加到工程
添加到network模块
6.3.1 添加头文件路径
出错:解决方法
6.4.1 编译
出错
解决方法:
6.5.1 mqtt初始化
QMQTT::Client *mqttClient ; QString clientID; qsrand(QTime(0,0,0).msecsTo(QTime::currentTime())); clientID = "XYD-CXX"+QString::number(qrand()); //合成 mqtt id //mqtt 初始化 mqttClient = new QMQTT::Client(ui->lEditServerIP->text(), 1883); mqttClient->setClientId(clientID); //ClientId 不能重复,不然会覆盖之前连接的人的 //mqttClient->setUsername("user"); //服务器账号密码,不需要则不用 //mqttClient->setPassword("password"); mqttClient->connect();
6.6.1mqtt信号与槽
//mqtt 连接成功 connect(mqttClient,SIGNAL(connected()),this,SLOT(doProcessMqttConnected())); //mqtt 退出成功 connect(mqttClient,SIGNAL(disconnected()),this,SLOT(doProcessMqttDisconnected())); //mqtt 订阅成功 connect(mqttClient,SIGNAL(subscribed(QString)),this,SLOT(doProcessMqttSubscribe(QSt ring))); //mqtt 订阅到消息 connect(mqttClient,SIGNAL(received(QMQTT::Message)),this,SLOT(doProcessMqttReceived (QMQTT::Message)));
6.7.1 MQTT发布
if(mqttIsConnected) { QMQTT::Message msg; msg.setTopic(ui->lEditPub->text()); //发布的主题 //发布的内容,QString 转 QByteArray msg.setPayload(ui->lEditPubPayload->text().toLatin1()); mqttClient->publish(msg); }
订阅成功的槽函数:一般不用这个
void MqttForm::doProcessMqttSubscribe(QString topic) { //qDebug()<< topic + "is Subscribe"; }
收到信息的槽函数:
void MqttForm::doProcessMqttReceived(QMQTT::Message msg) { qDebug() << "topic:" + msg.topic(); qDebug() << "payload:" + msg.payload(); }