MQTT协议原理介绍及如何使用emqx
什么是MQTT协议
MQTT(Message Queuing Telemetry Transport)协议是一种轻量级的、基于发布/订阅模式的通信协议。它最初由IBM开发,用于在低带宽和不稳定的网络环境中传输小型数据包。MQTT协议被广泛应用于物联网(IoT)领域,例如传感器数据采集、远程监控和控制等。
MQTT协议使用了一种异步的、非阻塞的消息传输模式。它包括三个主要组件:客户端、代理程序和主题(Topic)。客户端可以是发布者(Publisher)或订阅者(Subscriber),代理程序负责转发消息,主题用于标识消息的类型或内容。当一个客户端发布一个消息到一个主题上时,所有订阅该主题的客户端都会收到该消息。
MQTT协议具有以下特点:
- 轻量级:MQTT协议使用TCP/IP协议栈,但是它的数据包非常小,通信开销很小,适合在低带宽和不稳定的网络环境中使用。
- 灵活性:MQTT协议支持多种不同的QoS(Quality of Service)级别,以适应不同的应用场景。例如,可以选择仅发送一次或确保消息被送达至少一次或确保消息被送达一次且只被接收一次。
- 可靠性:MQTT协议具有较好的可靠性,即使在网络不稳定的情况下也能保持消息传输的可靠性和完整性。
- 安全性:MQTT协议支持传输层安全(TLS)协议和基于用户名和密码的认证机制,以确保通信的安全性。
据 Arlen Nipper 在 IBM Podcast 上的自述,MQTT 原名是 MQ TT
,注意 MQ
与 TT
之间的空格,其全称为: MQ Telemetry Transport,是九十年代早期他在参与 Conoco Phillips 公司的一个原油管道数据采集监控系统(pipeline SCADA system)时开发的一个实时数据传输协议。它的目的在于让传感器通过带宽有限的 VSAT ,与 IBM 的 MQ Integrator 通信。由于 Nipper 是遥感和数据采集监控专业出身,所以按业内惯例取了 MQ TT
这个名字。
MQTT 与其他协议对比
MQTT vs HTTP
- MQTT 的最小报文仅为 2 个字节,比 HTTP 占用更少的网络开销。
- MQTT 与 HTTP 都能使用 TCP 连接,并实现稳定、可靠的网络连接。
- MQTT 基于发布订阅模型,HTTP 基于请求响应,因此 MQTT 支持双工通信。
- MQTT 可实时推送消息,但 HTTP 需要通过轮询获取数据更新。
- MQTT 是有状态的,但是 HTTP 是无状态的。
- MQTT 可从连接异常断开中恢复,HTTP 无法实现此目标。
HTTP协议和SMTP协议都是基于TCP协议的,但是它们的数据包比MQTT协议大得多,通信开销也更大。在需要频繁传输小型数据包的应用场景中,MQTT协议的优势更加明显。
然而,MQTT协议也有一些缺点。例如,它只能传输小型数据包,不适合传输大型文件或数据流。另外,由于它是基于发布/订阅模式的,因此可能会存在消息丢失或消息重复的问题,需要根据实际应用场景来选择合适的QoS级别。
安全的双向通信机制
MQTT协议是一种基于发布/订阅模式的通信协议,它的双向通信机制是通过MQTT客户端与MQTT代理服务器之间的交互来实现的。下面是MQTT的双向通信机制的详细说明:
- 客户端向代理服务器发送消息:MQTT客户端可以向代理服务器发送消息,以实现从客户端到服务器的单向通信。客户端可以发布一个消息到一个或多个主题(Topic),代理服务器将根据主题的订阅情况将消息转发给订阅该主题的客户端。客户端可以选择不同的QoS级别来设置消息的可靠性和传输效率,例如QoS 0表示最多发送一次,QoS 1表示至少发送一次,QoS 2表示仅发送一次且确保消息只被接收一次。
- 代理服务器向客户端发送消息:MQTT代理服务器可以向客户端发送消息,以实现从服务器到客户端的单向通信。服务器可以订阅一个或多个主题,当有与该主题相关的消息发布时,代理服务器将转发该消息给订阅该主题的客户端。同样,服务器也可以选择不同的QoS级别来设置消息的可靠性和传输效率,例如QoS 0表示最多发送一次,QoS 1表示至少发送一次,QoS 2表示仅发送一次且确保消息只被接收一次。
- 客户端与代理服务器之间的双向通信:MQTT客户端和代理服务器之间的双向通信是通过客户端订阅一个或多个主题实现的。当代理服务器收到发布到该主题的消息时,它会将该消息转发给订阅该主题的客户端。客户端也可以向代理服务器发送订阅和取消订阅的请求,以动态地管理订阅关系。客户端还可以使用PINGREQ和PINGRESP消息来保持与代理服务器的心跳连接,以确保连接不会超时断开。
综上所述,MQTT的双向通信机制是通过客户端和代理服务器之间的发布/订阅模式实现的。客户端可以向代理服务器发送消息,并订阅一个或多个主题以接收代理服务器发送的消息。代理服务器可以向客户端发送消息,并根据客户端的订阅情况将消息转发给订阅相关主题的客户端。这种机制可以支持双向通信,并且非常适用于物联网等需要频繁传输小型数据包的应用场景。
如何使用emqx搭建MQTT服务端与客户端
emqx是一个基于Erlang语言开发的开源MQTT代理程序,它提供了一个可扩展的、高性能的MQTT消息传输服务。emqx支持多种QoS级别,以及基于WebSocket的MQTT传输协议。
以下是使用emqx搭建MQTT服务端和客户端的基本步骤:
在Linux上安装emqx服务器
官方网址:https://www.emqx.io/zh/downloads?os=Ubuntu
您可以在Linux上使用以下命令安装emqx:
curl -s https://assets.emqx.com/scripts/install-emqx-deb.sh | sudo bash
sudo apt-get install emqx
安装完成后,您可以使用以下命令启动emqx服务:
sudo systemctl start emqx
- 服务器地址:通常是您的服务器 IP 地址;
- 端口信息:可在 EMQX Dashboard 功能配置的监听器部分获取。
通过浏览器访问 http://localhost:18083/ (opens new window)(localhost 可替换为您的实际 IP 地址)以访问 EMQX Dashboard 管理控制台,进行设备连接与相关指标监控管理。
默认用户名及密码:
admin
public
使用MQTT客户端连接到emqx服务端
在编写MQTT客户端程序之前,您需要知道emqx服务端的IP地址和端口号。然后,您可以使用MQTT客户端库连接到emqx服务端。
在Python中,您可以使用以下代码连接到emqx服务端:
import paho.mqtt.client as mqtt
# MQTT服务端的IP地址和端口号
broker_address = "YOUR_BROKER_IP_ADDRESS"
broker_port = 1883
# 创建一个MQTT客户端实例
client = mqtt.Client()
# 连接到MQTT服务端
client.connect(broker_address, broker_port)
# 启动MQTT客户端循环
client.loop_start()
# 发布消息到MQTT服务端
topic = "test"
payload = "Hello, World!"
client.publish(topic, payload)
# 订阅MQTT主题
topic = "test"
def on_message(client, userdata, message):
print(message.topic,message.payload.decode())
client.subscribe(topic)
client.on_message = on_message
# 保持MQTT客户端连接
while True:
pass
在上面的代码中,我们使用paho-mqtt客户端库连接到emqx服务端,并发布一条消息到test主题。然后,我们订阅test主题,并在收到消息时打印出来。
在emqx服务端上配置ACL(访问控制列表)
为了保证MQTT通信的安全性,您可以在emqx服务端上配置ACL来限制访问。ACL可以控制哪些客户端可以连接到MQTT服务端,哪些客户端可以发布消息或订阅主题等。
以下是一个ACL配置文件的示例:
## emqx.access
## -------------------------------------------------------------------
## emqx access control configuration file.
##
## GitHub: https://github.com/emqx/emqx/tree/master/etc/plugins/access
##
## -------------------------------------------------------------------
## sys.* Topics
## -------------------------------------------------------------------
allow sys
## Anonymous users
## -------------------------------------------------------------------
## allow anonymous publish/subscribe
## allow anonymous subscribe only to the public topics
## deny anonymous publish/subscribe
##
## pattern: $anonymous
##
## allow $anonymous publish to the public topics
allow $anonymous read public/*
allow $anonymous write public/+
## allow $anonymous subscribe only to the public topics
allow $anonymous subscribe public/+
## deny $anonymous publish to any topics
deny $anonymous
## Clients with username "public"
## -------------------------------------------------------------------
## allow "public" publish/subscribe
## allow "public" subscribe only to the public topics
## deny "public" publish/subscribe to the "private" topics
##
## pattern: username/public
##
## allow username/public publish to the public topics
allow username/public read public/+
allow username/public write public/+
## allow username/public subscribe only to the public topics
allow username/public subscribe public/+
## deny username/public publish/subscribe to the private topics
deny username/public write private/+
deny username/public read private/+
## Clients with username "admin"
## -------------------------------------------------------------------
## allow "admin" publish/subscribe to any topics
##
## pattern: username/admin
##
## allow username/admin publish/subscribe to any topics
allow username/admin
在上面的ACL配置文件中,我们定义了三个规则:
- 系统主题(sys. *)可以被任何客户端访问。
- 匿名用户可以订阅和发布public主题,但不能订阅和发布private主题。
- 用户名为public的客户端可以订阅和发布public主题,但不能订阅和发布private主题。
您可以根据您的实际需求修改ACL配置文件,并将其保存为emqx.access文件。然后,将emqx.access文件复制到emqx的etc/plugins/access目录下,并重新启动emqx服务。
sudo cp emqx.access /etc/emqx/plugins/access/
sudo emqx restart
通过MQTTX 测试
mqttx是集桌面应用、命令行工具与 Web 应用于一体的全功能 MQTT 客户端工具。是 EMQX 开源的一款跨平台 MQTT 5.0 客户端工具,它支持 macOS、Linux、Windows,并且支持自定义脚本模拟测试、MQTT 消息格式转换、日志记录等多个功能。您可通过 MQTTX 一键式的连接方式和图形界面,您可轻松测试 MQTT/TCP、MQTT/TLS、MQTT/WebSocket 连接。
官网:https://mqttx.app/zh/features
配置并建立 MQTT 连接。点击 + 新建连接 进入配置页面,只需配置:
-
名称:连接名称,如 MQTTX_Test;
-
服务器地址
- 通过选择该连接的协议类型,如 WebSockets 协议,ws://;目前 MQTTX Web 端仅支持 WebSocket 协议,如希望测试 SSL/TLS 认证连接,请下载 MQTT 客户端 (opens new window);
- 填入之前获取的 EMQX 地址,如 emqx@127.0.0.1
-
端口:如 WebSockets 协议对应的 8083 端口
其他项目保持默认配置,你也可以根据具体业务场景修改。
总结
MQTT协议是一种轻量级的、基于发布/订阅模式的通信协议,适用于物联网领域。emqx是一个基于Erlang语言开发的开源MQTT代理程序,它可以提供可扩展的、高性能的MQTT消息传输服务。在本文中,我们介绍了MQTT协议的基本原理,并演示了如何使用emqx搭建MQTT服务端和客户端。我们还介绍了如何在emqx服务端上配置ACL以保证MQTT通信的安全性。