美文网首页TCP/IP协议
MQTT协议笔记之连接和心跳

MQTT协议笔记之连接和心跳

作者: XLsn0w | 来源:发表于2017-12-12 16:27 被阅读57次

    MQTT有关字符串部分采用的修改版的UTF-8编码,CONNECT可变头部中协议名称、消息体都是采用修改版的UTF-8编码。前面基本上可变头部内容不多,下面是一个较为完整的CONNECT消息结构:

    可变头部

    协议名称和协议版本都是固定的。

    连接标志(Connect Flags)

    一个字节表示,除了第1位是保留未使用,其它7位都具有不同含义。

    业务上很重要,对消息总体流程影响很大,需要牢记。

    Clean Session

    0,表示如果订阅的客户机断线了,要保存为其要推送的消息(QoS为1和QoS为2),若其重新连接时,需将这些消息推送(若客户端长时间不连接,需要设置一个过期值)。 1,断线服务器即清理相关信息,重新连接上来之后,会再次订阅。

    Will Flag

    定义了客户端(没有主动发送DISCONNECT消息)出现网络异常导致连接中断的情况下,服务器需要做的一些措施。

    简而言之,就是客户端预先定义好,在自己异常断开的情况下,所留下的最后遗愿(Last Will),也称之为遗嘱(Testament)。 这个遗嘱就是一个由客户端预先定义好的主题和对应消息,附加在CONNECT的可变头部中,在客户端连接出现异常的情况下,由服务器主动发布此消息。

    只有在Will Flag位为1时,Will Qos和Will Retain才会被读取,此时消息体payload中要出现Will Topic和Will Message具体内容,否则,Will QoS和Will Retain值会被忽略掉。

    Will Qos

    两位表示,和PUBLISH消息固定头部的QoS level含义一样。这里先掠过,到PUBLISH消息再回过头来看看,会更明白些。

    若标识了Will Flag值为1,那么Will QoS就会生效,否则会被忽略掉。

    Will RETAIN

    如果设置Will Flag,Will Retain标志就是有效的,否则它将被忽略。

    当客户端意外断开服务器发布其Will Message之后,服务器是否应该继续保存。这个属性和PUBLISH固定头部的RETAIN标志含义一样,这里先掠过。

    User name 和 password Flag:

    用于授权,两者要么为0要么为1,否则都是无效。都为0,表示客户端可自由连接/订阅,都为1,表示连接/订阅需要授权。

    Payload/消息体

    消息体定义的消息顺序(如上表所示),约定俗成,不得更改,否则将可能引起混乱。

    若Will Flag值为0,那么在payload中,Client Identifer后面就不会存在Will Topic和Will Message内容。

    若User Name和Password都为0,意味着Payload/消息体中,找不到User Name和password的值,就算有,也是无效。标志决定着是否读取与否。

    心跳时间(Keep Alive timer)

    以秒为单位,定义服务器端从客户端接收消息的最大时间间隔。一般应用服务会在业务层次检测客户端网络是否连接,不是TCP/IP协议层面的心跳机制(比如开启SOCKET的SO_KEEPALIVE选项)。 一般来讲,在一个心跳间隔内,客户端发送一个PINGREQ消息到服务器,服务器返回PINGRESP消息,完成一次心跳交互,继而等待下一轮。若客户端没有收到心跳反馈,会关闭掉TCP/IP端口连接,离线。 16位两个字节,可看做一个无符号的short类型值。最大值,2^16-1 = 65535秒 = 18小时。最小值可以为0,表示客户端不断开。一般设为几分钟,比如微信心跳周期为300秒。

    Will Message编码

    Will Message在CONNECT Payload/息体中,使用UTF-8编码。假设内容为“abcd”,大概如下:

    连接异常中断通知机制

    CONNECT消息一旦设置在可变头部设置了Will flag标记,那就启用了Last-Will-And-Testament特性,此特性很赞。

    一旦客户端出现异常中断,便会触发服务器发布Will Message消息到Will Topic主题上去,通知Will Topic订阅者,对方因异常退出。

    接收CONNECT后的响应动作

    接收到CONNECT消息之后,服务器应该返回一个CONNACK消息作为响应:

    若客户端绕过CONNECT消息直接发送其它类型消息,服务器应关闭此非法连接 若客户端发送CONNECT之后未收到CONNACT,需要关闭当前连接,然后重新连接

    相同Client ID客户端已连接到服务器,先前客户端必须断开连接后,服务器才能完成新的客户端CONNECT连接 客户端发送无效非法CONNECT消息,服务器需要关闭

    CONNACK

    一个完整的CONNACK消息大致如下:

    相关文章

      网友评论

        本文标题:MQTT协议笔记之连接和心跳

        本文链接:https://www.haomeiwen.com/subject/zhsnixtx.html