MQTT通信协议介绍
一:MQTT协议介绍
MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议,它是一种轻量级的、基于代理的“发布/订阅”模式的消息传输协议。其具有协议简洁、小巧、可扩展性强、省流量、等优点。可在不可靠的网络环境中进行扩展,适用于设备硬件存储空间或网络带宽有限的场景。使用MQTT协议,消息发送者与接收者不受时间和空间的限制。物联网平台支持设备使用MQTT协议接入。
二:MQTT协议的主要特点
1、使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合
2、使用 TCP/IP 提供网络连接
3、有三种级别的消息发布服务质量QoS(Quality of Service)
“至多一次”(Qos = 0),消息发布完全依赖底层 TCP/IP 网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。
“至少一次”(Qos = 1),确保消息到达,但消息重复可能会发生。
“只有一次”(Qos = 2),确保消息到达一次。消息丢失和重复都是不可接受的,使用这个服务质量等级会有额外的开销。
三:MQTT协议的核心角色
MQTT 协议主要有三大核心角色:发布者(Publisher)、Broker代理服务器(转发者) 、订阅者(Subscriber) 。其中消息的发布者和订阅者都是客户端(Client)角色,消息代理是服务器,消息发布者可以同时是订阅者。 当Client发布某个主题的消息时,Broker会将该消息分发给任何已订阅该主题的Client。
MQTT服务器
MQTT服务端通常是一台服务器。它是MQTT信息传输的枢纽,负责将MQTT客户端发送来的信息传递给MQTT客户端。MQTT服务端还负责管理MQTT客户端。确保客户端之间的通讯顺畅,保证MQTT消息得以正确接收和准确投递。
MQTT客户端
MQTT客户端可以向服务端发布信息,也可以从服务端收取信息。我们把客户端发送信息的行为成为“发布”信息。而客户端要想从服务端收取信息,则首先要向服务端“订阅”信息。“订阅”信息这一操作很像我们在微信中订阅的公众号,当公众号更新时,微信会向订阅了该公众号的用户发送信息,告诉他们有文章更新了。
MQTT主题
刚刚我们在讲解MQTT客户端订阅信息时,使用了用户在微信中订阅公众号的这个例子。在MQTT通讯中,客户端所订阅的肯定不是一个个公众号,而是一个个“主题”。MQTT服务端在管理MQTT信息通讯时,就是使用“主题”来控制的。
四:连接MQTT服务端
MQTT客户端要想通讯,必须经过MQTT服务端。因此MQTT客户端无论是发布消息还是订阅消息,首先都要连接MQTT服务端。下面我们看一下MQTT客户端连接服务端的详细过程。
1、首先MQTT客户端将会向服务端发送连接请求。该请求实际上是一个包含有连接请求信息的数据包。这个数据包的官方名称为CONNECT 2、MQTT服务端收到客户端连接请求后,会向客户端发送连接确认。同样的,该确认也是一个数据包。这个数据包官方名称为CONNACK。
以上就是MQTT客户端在连接服务端的两步操作。接下来,我们一起来了解一下客户端在连接服务端时所发送的CONNECT报文内容。
clientId – 客户端ID
ClientId是MQTT客户端的标识。MQTT服务端用该标识来识别客户端。因此ClientId必须是独立的。如果两个MQTT客户端使用相同ClientId标识,服务端会把它们当成同一个客户端来处理。通常ClientId是由一串字符所构成的
username(用户名)和password(密码)
这里的用户名和密码是用于客户端连接服务端时进行认证需要的。有些MQTT服务端需要客户端在连接时提供用户名和密码。只有客户端正确提供了用户名和密码后,才能连接服务端。否则服务端将会拒绝客户端连接,那么客户端也就无法发布和订阅消息了。
username(用户名)和password(密码)是可选的CONNECT信息。也就是说,有些服务端开启了客户端用户密码认证,这种服务端需要客户端在连接时正确提供认证信息才能连接。当然,那些没有开启用户密码认证的服务端无需客户端提供用户名和密码认证信息
cleanSession – 清除会话
要说明cleanSession的具体含义,首先要从MQTT网络环境讲起。MQTT客户端与服务端的连接可能不是非常稳定,在不稳定的网络环境下,要想保证所有信息传输都能够做到准确无误,这是非常困难的。
为了保证重要的MQTT报文可以被客户端准确无误的收到。在服务端向客户端发送报文后,客户端会向服务端返回一个确认报文。如果服务端没有收到客户端返回的确认报文,那么服务端就会认为刚刚发送给客户端的报文没有被准确无误的送达。在这种情况下,服务端将会执行以下两个操作:
1、将尚未被客户端确认的报文保存起来
2、再次尝试向客户端发送报文,并且再次等待客户端发来确认信息。
如果 cleanSession 被设置为“true”。那么服务端不需要客户端确认收到报文,也不会保存任何报文。在这种情况下,即使客户端错过了服务端发来的报文,也没办法让服务端再次发送报文。 反过来,如果我们将 cleanSession 设置为”false”。那么服务端就知道,后续通讯中,客户端可能会要求我保存没有收到的报文。
keepAlive – 心跳时间间隔
MQTT服务端运行过程中,当有客户端因为某种原因断开了与服务端的连接,服务端需要实时了解这一情况。KeepAlive正是用于服务端了解客户端连接情况的。
客户端在没有向服务端发送信息时,可以定时向服务端发送一条消息。这条用于心跳机制的消息也被称作心跳请求。
心跳请求的作用正是用于告知服务端,当前客户端依然在线。服务端在收到客户端的心跳请求后,会回复一条消息。这条回复消息被称作心跳响应。
客户端在心跳间隔时间内,如果有消息发布,那就直接发布消息而不发布心跳请求,但是在心跳间隔时间内,客户端没有消息发布,那么它就会发布一条心跳请求给服务端,这个心跳请求的目的就是为了告诉服务端,我还在线。
五: SUBSCRIBE – 订阅主题
当客户端连接到服务端后,除了可以发布消息,也可以接收消息。所有MQTT消息都有主题。客户端要想接收消息,首先要订阅该消息的主题。这样,当有客户端向该主题发布消息后,订阅了该主题的客户端就能接收到消息了。
客户端要想订阅主题,首先要向服务端发送主题订阅请求。客户端是通过向服务端发送SUBSCRIBE报文来实现这一请求的。客户端在订阅主题时也可以明确QoS。服务端会根据SUBSCRIBE中的QoS来提供相应的服务保证。