MQTT客户端之间要想实现通讯,必须要通过MQTT服务端。因此MQTT客户端无论是发布消息还是订阅消息,首先都要连接MQTT服务端。
MQTT客户端连接服务端一共有两步。
第一步(CONNECT请求)
首先MQTT客户端将会向服务端发送连接请求。该请求实际上是一个包含有连接请求信息的数据包。这个数据包的官方名称为CONNECT.
下图是CONNECT报文所包含的信息内容。
下面讲解下这些必填的信息。
clientId – 客户端ID(对于同一个服务器,不能有相同的客户端ID)
ClientId是MQTT客户端的标识。MQTT服务端用该标识来识别客户端。因此ClientId必须是独立的。如果两个MQTT客户端使用相同ClientId标识,服务端会把它们当成同一个客户端来处理。通常ClientId是由一串字符所构成的,如上图所示,此示例中的clientID是“client-1”。
cleanSession – 清除会话
MQTT客户端与服务端的连接可能不是非常稳定,在不稳定的网络环境下,要想保证所有信息传输都能够做到准确无误,这是非常困难的。因此,我们就要根据客户端对系统运行的重要性来区别对待。
为了保证重要的MQTT报文可以被客户端准确无误的收到。在服务端向客户端发送报文后,客户端会向服务端返回一个确认报文。如果服务端没有收到客户端返回的确认报文,那么服务端就会认为刚刚发送给客户端的报文没有被准确无误的送达。在这种情况下,服务端将会执行以下两个操作:
操作1:将尚未被客户端确认的报文保存起来
操作2:再次尝试向客户端发送报文,并且再次等待客户端发来确认信息。
如果cleanSession填的值是true,那么服务端不需要客户端确认收到报文,也不会保存任何报文。
如果cleanSession填的值是false,服务端会把这些没有收到确认的数据保存起来,不断尝试将这些重要信息再次发送给客户端,直到收到确认信息。
请注意,如果需要服务端保存重要报文,光设置cleanSession 为false是不够的,还需要传递的MQTT信息QoS级别大于0。
keepAlive – 心跳时间间隔
MQTT服务端运行过程中,当有客户端因为某种原因断开了与服务端的连接,服务端需要实时了解这一情况。KeepAlive (心跳时间间隔)正是用于服务端了解客户端连接情况的。
例如这里设置的是60,则客户端每60s发送一个心跳信息给服务端,告诉服务端我和你还在连着。
第二步(CONNACK确认)
MQTT服务端收到客户端连接请求后,会向客户端发送连接确认。同样的,该确认也是一个数据包。这个数据包官方名称为CONNACK。
下图是CONNACK报文所包含的信息内容。
returnCode – 连接返回码
当服务端收到了客户端的连接请求后,会向客户端发送returnCode(连接返回码),用以说明连接情况。如果客户端与服务端成功连接,则返回数字“0”。如果未能成功连接,连接返回码将会是一个非零的数值,具体这个数值的含义,请见下表:
sessionPresent – 当前会话
要说明sessionPresent,首先我们要回顾一下CONNECT报文中的cleanSession – 清除会话。当cleanSession 设置为false时,如果服务端发送给客户端数据没有得到确认,就会把数据保存下来。如果一直没有得到确认,则会出现一下情况:
当重要客户端连接服务端时,服务端可能保存着没有得到确认的报文。如果是这样的话,那么客户端在连接服务端时,就会通过sessionPresent来了解服务端是否有之前未能确认的信息,那么sessionPresent此时的值就会时true。
总结来说:如果sessionPresent为true,那么服务端还存在着上一次连接时没有被客户端确认的信息。