# MQTT 服务器/客户端配置文档 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于 Publish / Subscribe(发布/订阅)模式的 "轻量级" 通讯协议,该协议构建于 TCP/IP L4 Layer 之上,由 IBM 在 1999 年发布。是为了硬件性能低下的远程设备以及网络状况糟糕的场景中而设计的发布/订阅型消息协议,为此,它需要一个消息中间件(Broker)。 MQTT 最大优点在于:可以以极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。作为一种低开销、低带宽占用的即时通讯协议,使其在物联网、小型设备、移动应用等方面有较广泛的应用。 MQTT 协议的缺省 Port: - 1883 - 8883 ## MQTT 的设计原则 1. 精简,不添加可有可无的功能; 2. 发布/订阅(Pub/Sub)模式,方便消息在传感器之间传递; 3. 允许用户动态创建 Topic,零运维成本; 4. 把传输量降到最低以提高传输效率; 5. 把低带宽、高延迟、不稳定的网络等因素考虑在内; 6. 支持连续的会话控制; 7. 理解客户端计算能力可能很低; 8. 提供服务质量管理; 9. 假设数据不可知,不强求传输数据的类型与格式,保持灵活性。 ## MQTT 的实现原理 在 MQTT 协议的通讯过程中,存在三种角色: 1. **发布者(Publish)** 2. **代理者(Broker)** 3. **订阅者(Subscribe)** 其中,消息的发布者和订阅者都是 MQTT Client,只有消息代理者是 MQTT Server,消息发布者可以同时也可以是订阅者。 MQTT Client 可以: - 与服务器建立连接。 - 发布其他客户端可能会订阅的信息; - 订阅其它客户端发布的消息; - 退订或删除其他客户端的消息; - 断开与服务器连接。 MQTT Server 可以: - 接受来自客户端的网络连接; - 接受客户端发布的应用信息; - 处理来自客户端的订阅和退订请求; - 向订阅的客户端转发应用程序消息。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210415202226592.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ptaWxr,size_16,color_FFFFFF,t_70) MQTT Message 分为两部分: 1. **主题(Topic)**:可以理解为消息的类型,发布者发布一个 “主题”,订阅者选择订阅若干个 “主题”。订阅者订阅(Subscribe)后,且发布者发布消息后,就会收到该主题(Topic)的消息内容(Payload); 2. **负载(Payload)**:可以理解为消息的内容,是指订阅者具体要使用的内容。 当应用数据通过 MQTT 网络进行传输时,MQTT 会把与之相关的 QoS 与 Topic 关联起来。 ## MQTT 的关键术语 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210416120111470.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ptaWxr,size_16,color_FFFFFF,t_70) **订阅(Subscription)**:包含 Topic Filter(主题筛选器)和 QoS。Subscription 会与一个 Session 关联。一个 Session 可以关联多个 Subscription。每一个 Session 中的每个 Subscription 都有一个不同的 Topic Filter。 **会话(Session)**:Client 与 Server 建立的连接就是一个 Session,Client 和 Server 之间进行有状态的交互。 **主题名(Topic Name)**:是一个标签,与 Server 的 Subscription 相匹配。Server 会将消息发送给 Subscription 所匹配标签的每个 Client。 **主题筛选器(Topic Filter)**:一个针对 Topic Name 的通配符筛选器,在订阅表达式中使用,表示订阅所匹配到的多个主题。 **负载(Payload)**:消息订阅者所具体接收的内容。 ## MQTT 的方法 MQTT 协议中定义了一些方法(也被称为动作),来于表示对确定资源所进行操作。这个资源可以代表预先存在的数据或动态生成数据,这取决于服务器的实现。通常来说,资源指服务器上的文件或输出。 主要方法有: - **Connect**:等待与服务器建立连接。 - **Disconnect**:等待 MQTT 客户端完成所做的工作,并与服务器断开 TCP/IP 会话。 - **Subscribe**:等待完成订阅。 - **UnSubscribe**:等待服务器取消客户端的一个或多个 Topics 订阅。 - **Publish**:MQTT 客户端发送消息请求,发送完成后返回应用程序线程。 ## MQTT 报文结构 一个 MQTT 报文由以下 3 个部分构成: 1. 固定头(Fixed header):存在于所有 MQTT 报文中,表示报文类型及报文的分组类标识。 2. 可变头(Variable header):存在于部分 MQTT 报文中,报文类型决定了可变头是否存在及其具体内容。 3. 消息体(Payload):存在于部分 MQTT 报文中,表示客户端收到的具体内容。 ## Linux MQTT Server - 安装 mosquitto ```bash yum install gcc-c++ cmake openssl-devel -y wget http://mosquitto.org/files/source/mosquitto-1.6.8.tar.gz tar -zxvf mosquitto-1.6.8.tar.gz cd mosquitto-1.6.8 make && make install ln -s /usr/local/lib/libmosquitto.so.1 /usr/lib/libmosquitto.so.1 ldconfig ``` - 配置 ```bash $ vi /opt/mosquitto-1.6.8/mosquitto.conf ... user root ``` - 启动 MQTT Server ```bash $ mosquitto -c /opt/mosquitto-1.6.8/mosquitto.conf -d $ ps -aux | grep mosquitto root 6603 0.0 0.0 22428 2768 ? Ss 12:20 0:00 mosquitto -c /opt/mosquitto-1.6.8/mosquitto.conf -d $ netstat -lpntu | grep mosquitto tcp 0 0 0.0.0.0:1883 0.0.0.0:* LISTEN 6603/mosquitto tcp6 0 0 :::1883 :::* LISTEN 6603/mosquitto ``` - 启动 MQTT 订阅者 ```bash $ mosquitto_sub -t topic # mosquitto_sub 命令参数说明。 # -c 设定 ‘clean session’ 为无效状态,这样一直保持订阅状态,即便是已经失去连接,如果再次连接仍旧能够接收的断开期间发送的消息。 # -d 打印 debug 信息。 # -h 指定要连接的域名 默认为 localhost。 # -i 指定 clientId。 # -I 指定 clientId 前缀。 # -k keepalive 每隔一段时间,发 PING 消息通知 Broker,仍处于连接状态。 默认为 60 秒。 # -q 指定希望接收到什么 QoS 的消息 默认 QoS 为 0。 # -R 不显示陈旧的消息。 # -t 指定订阅的 Topic。 # -v 打印消息。 # --will-payload 指定一个消息,该消息当 Client 与 Broker 意外断开连接时发出。该参数需要与 --will-topic 一起使用。 # --will-qos 指定 Will 的 QoS 值。该参数需要与 --will-topic 一起使用。 # --will-retain 指定 Will 消息被当做一个 retain 消息(即消息被广播后,该消息被保留起来)。该参数需要与 --will-topic 一起使用。 # --will-topic 指定用户发送 Will 消息的 Topic。 ``` - 启动 MQTT 发布者 ```bash mosquitto_pub -t topic -m "HELLO" # mosquitto_pub 命令参数说明: # -d 打印 debug 信息。 # -f 将指定文件的内容作为发送消息的内容。 # -h 指定要连接的域名 默认为 localhost。 # -i 指定给哪个 clientId 的用户发送消息。 # -I 指定给哪个 clientId 前缀的用户发送消息。 # -m 消息内容。 # -n 发送一个空(null)消息。 # -p 连接端口号。 # -q 指定 QoS 的值(0,1,2)。 # -t 指定 Topic Name # -u 指定 Broker 访问用户。 # -P 指定 Broker 访问密码。 # -V 指定 MQTT 协议版本。 # --will-payload 指定一个消息,该消息当 Client 与 Broker 意外断开连接时发出。该参数需要与 --will-topic 一起使用。 # --will-qos 指定 Will 的 QoS 值。该参数需要与 --will-topic 一起使用。 # --will-retain 指定 Will 消息被当做一个 retain 消息(即消息被广播后,该消息被保留起来)。该参数需要与 --will-topic 一起使用。 # --will-topic 用户发送 Will 消息的 Topic。 ``` ## Android MQTT Client **蘑菇 IoT**: - 连接到 MTTT Server ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210416131615538.jpeg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ptaWxr,size_16,color_FFFFFF,t_70) - 订阅一个 Topic ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210416131658747.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ptaWxr,size_16,color_FFFFFF,t_70) - 发布消息到一个 Topic ![在这里插入图片描述](https://img-blog.csdnimg.cn/2021041613171242.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ptaWxr,size_16,color_FFFFFF,t_70)