名字
服务端发送 CONNACK 报文响应从客户端收到的 CONNECT 报文。在发送除了 AUTH 报文以外的其它任何报文之前,服务器必须发送一个带有 0x00(成功)原因码的 CONNACK 报文。[MQTT-3.2.0-2]服务器不能在单个连接中发送多个 CONNACK 报文。[MQTT-3.2.0-2]
如果客户端在合理的时间内没有收到服务端的CONNACK报文,客户端应该关闭网络连接。合理 的时间取决于应用的类型和通信基础设施。
固定报头的格式见 图例 3.8 – CONNACK 报文固定报头 的描述。
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
byte 1 | MQTT报文类型 (2) | Reserved 保留位 | ||||||
0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | |
byte 2 | 剩余长度 (2) | |||||||
0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
剩余长度字段
表示可变报头的长度。对于CONNACK报文这个值等于2。
CONNACK 报文的可变报头依次包含了以下几个字段:连接确认标识,连接原因码以及属性。属性的编码规则在2.2.2 节 中已经描述过了。
第 1 个字节是 连接确认标志,位 7-1 是保留位且必须设置为0。[MQTT-3.2.2-1]
第 0 位 是当前会话(Session Present)标志。
位置:连接确认标识的第0位。
当前会话标识通知客户端:是否服务器为该客户端标识符使用了前一个连接的会话状态。这保证客户端和服务器的会话状态的视图是一致的。
如果服务器接收的连接将清除开始(Clean Start) 设为 1,服务器除了 必须 在 CONNACK 报文中将当前会话的值设为 0 以为,还需要在 CONNACK 报文中设置一个 0x00(成功) 的原因码。[MQTT-3.2.2-2]
如果服务器接收的连接将清除开始(Clean Start) 设为 0,且服务器已经有了该客户端标识符的会话状态,那么它必须将 在 CONNACK 报文中将当前会话设为 1,否则它必须在 CONNACK 报文中将当前会话设置为 0。无论是上述两种情况的哪一种,都必须在 CONNACK 报文中设置一个 0x00(成功)的原因码。[MQTT-3.2.2-3]
如果客户端从服务器那里接收到的当前会话的值不符合预期,客户端应该按照以下方式去处理:
如果服务器发送了一个包含非 0 原因码的 CONNACK 报文,它必须将当前会话设为 0。[MQTT-3.2.2-6]
可变报头的第二个字节是连接原因码。
下表是连接原因码的值。如果从服务器那里接收到一个格式良好的 CONNECT 报文,但是服务器不能完成连接,服务器可以发送一个包含适合的连接原因码(见下表)的 CONNACK 报文。如果服务器发送的 CONNACK 报文中的原因码大于等于 128,那么它必须立刻关闭网络连接[MQTT-3.2.2-7]
表 3-1 - 连接原因码的值
值 | 十六进制 | 原因码名称 | 描述 |
---|---|---|---|
0 | 0x00 | 成功 | 接受连接。 |
128 | 0x80 | 未指定错误 | 服务器无意揭示失败原因或者其它原因码无法解释该错误原因。 |
129 | 0x81 | 畸形报文 | CONNECT 报文中的数据无法被正确解析。 |
130 | 0x82 | 协议错误 | CONNECT 包中的数据与协议标准不一致。 |
131 | 0x83 | 实现特定的错误 | CONNECT 报文有效但是不被服务器接收。 |
132 | 0x84 | 不支持的协议版本 | 服务器不支持客户端传来的 MQTT 报文的协议标准。 |
133 | 0x85 | 客户端标识符无效 | 客户端标识符是一个有效字符串但却没有被服务器接收。 |
134 | 0x86 | 错误的用户名和密码 | 服务器不接受客户端指定的用户名和密码。 |
135 | 0x87 | 未被授权 | 客户端没有被授权去连接。 |
136 | 0x88 | 服务器不可用 | MQTT 服务器不可用。 |
137 | 0x89 | 服务器繁忙 | 服务器繁忙,之后重试。 |
138 | 0x8A | 被禁止了 | 客户端被管理员禁止访问了,需要联系管理员 |
140 | 0x8C | 错误的验证方法 | 不支持验证方法, 或无法匹配当前验证方法 |
144 | 0x90 | 主题名无效 | 遗嘱主题名的格式没有问题但不被服务器接收 |
149 | 0x95 | 报文太大 | 包的大小超过了允许的最大值 |
151 | 0x97 | 超出配额 | 超出实现或管理的限制 |
153 | 0x99 | 有效载荷格式无效 | 遗嘱有效载荷没有匹配到指定的有效载荷格式指示器。 |
154 | 0x9A | 保留不支持 | 服务器不支持保留消息且遗嘱保留设为了 1 |
155 | 0x9B | QoS 不支持 | 服务器不支持在遗嘱 QoS 中设置 QoS 等级。 |
156 | 0x9C | 使用另一台服务器 | 客户端应该暂时使用另一台服务器。 |
157 | 0x9D | 服务器被移除 | 客户端应该使用另一台服务器。 |
159 | 0x9F | 连接速率超出 | 超出连接速率的限制。 |
服务器发送的 CONNACK 报文必须使用上表连接原因码值中的其中一个值。[MQTT-3.2.2-8]
非正式评注
原因码 0x80 (未指定错误)可以被用于服务器已知失败原因却无意告诉客户端的情况或者没有其它原因码可应用的情况。
在 CONNECT 报文上发现错误的情况下,服务器可以选择关闭网络连接而不是发送 CONNACK 以增强安全性。例如,当在公共网络上并且连接没有被授权时,指示这是 MQTT 服务器可能是不明智的。
用不定长字节整形来编码的 Properties 长度
17(0x11)字节 ,会话过期间隔标识符。
四个字节整形表示的会话到期间隔,单位是秒,如果这个属性在一个控制包中出现了两次,就会视为协议错误。
如果在被使用的 CONNECT 报文中没有设置会话到期间隔。服务器会使用该属性来通知客户端使用该值而非客户端发送的 CONNACK 报文中的属性到期间隔值。
33(0x21)字节,接收最大值标识符。
接收最大值由 2 个字节的整形来表示,如果单个报文中该属性出现了多次,或它的值为 0,则协议错误。
服务器通过使用这个值来限制同时并行处理 QoS1 和 QoS2 发布的消息数量。现在还没有机制来限制服务器可能会发布的 QoS0 消息。
如果没有设置接收最大值,那么它的值会被设为默认值-65,535。
请参阅4.9 节中的流程控制,去了解如何使用接收最大值。
36(0x24)字节,QoS 最大值标识符。
该属性占一个字节,仅能表示 1 或者 0 两个值,若该属性在同一报文中重复出现,那么就会被视为协议错误。如果没有设定该属性,客户端就会使用 QoS 为 2 的值。
如果服务器不支持 QoS1 或 QoS2 的 PUBLISH 包,那它就必须在 CONNACK 报文中发送一个 QoS 最大值来指定它支持的最高 QoS 值[MQTT-3.2.2-9]。不支持 QoS1 或 QoS2 的 PUBLISH 报文的服务器仍需接收包含请求 QoS0,1或2 的 SUBSCRIBE 报文[MQTT-3.2.2-10]。
如果客户端从服务器那里收到 QoS 最大值后,就不能再发送超出那一 QoS 等级的 PUBLISH 报文了[MQTT-3.2.2-11],否则将视为协议错误,通过发送一个带有0x9B(不支持的 QoS)原因码的 DISCONNECT 报文来处理错误。如果收到的 CONNECT 报文中遗嘱 QoS 的 QoS 值也超出那一限制,就会将其视为协议错误,并发送一个带有 0x9B 原因码的 CONNACK 包来处理错误。
如果服务器接收到包含超出其功能的遗嘱 QoS 的 CONNECT 报文,它必须 拒绝连接。它应该如同在4.13 节错误处理所描述的那样去使用一个带有 0x9B(不支持的 QoS)原因码 的 CONNACK 报文并且必须关闭网络连接[MQTT-3.2.2-12]。
非正式评注
客户端不需要支持 QoS 1 或 QoS2 的 PUBLISH 报文。如果是这种情况,客户端只需将其发送的任何SUBSCRIBE命令中的最大QoS字段限制为它可以支持的值。
37(0x25)字节,保留可用的标识符。
该属性占据一个字节,如果存在该属性,则用来声明服务器是否支持保留消息,0 代表不支持, 1 代表支持,如果不存在该属性,则代表支持,如果该属性在同一报文中重复出现或表示的值不是 0 或 1,那就会触发协议错误。
如果服务器收到一个包含遗嘱保留(Will Retain)为 1 的遗嘱消息的 CONNECT 报文,且它不支持保留消息,服务器必须拒绝连接请求。它应该发送一个带有0x9A (不支持保留)原因码的 CONNACK 报文,然后它必须关闭连接。[MQTT-3.2.2-13]。
如果客户端从服务器那里收到的保留可用的值设为 0,那么服务器不能发送一个带有保留标识设为 1 的 PUBLISH 报文[MQTT-3.2.2-14]。 如果服务器接收到这样的报文,那么就会引发协议错误。服务器应该如同4.13 节 所描述的那样发送一个带有原因码为 0x9A(不支持保留)的 DISCONNECT 报文。
39(0x27)字节,最大报文长度标识符。
接收最大值由 4 个字节的整形来表示客户端愿意接收的最大报文长度,如果不存在最大报文长度属性,作为剩余长度编码和协议头大小的结果,除了协议的限制外,不限制数据包大小。
如果单个报文中该属性出现了多次,或当其值设为 0 时,则协议错误。
正如2.1.4 节所定义的那样,这里的报文大小指的是整个 MQTT 控制包的所有字节数。客户端使用最大报文大小来通知服务器,让它不要处理超过这个大小的数据包。
服务器 不能 发送超过最大报文长度的包给客户端。[MQTT-3.1.2-24]如果客户端收到了超出限制的报文,那么会视为协议错误。如同4.13 节所描述的那样,服务器会在断开连接的时候返回一个带有 0x95(报文太大)原因码的 DISCONNECT 报文
18(0x12)字节,已分配客户端标识符的标识符。
由一个 UTF-8 的字符串表示,若在同一报文中重复出现该属性,则被视为协议错误。
由于 0 长度的客户端标识符在 CONNECT 报文中被发现了,因此客户端标识符会由服务器来分配。
如果客户端连接的时候使用了一个 0 长度的客户端标识符,服务器必须用一个包含已分配客户端标识符的 CONNACK 报文来响应。被分配的客户端标识符必须是一个新的未被任何在服务器上现存的其它会话所使用的客户端标识符[MQTT-3.2.2-16]
34(0x22)字节,主题别名最大数量标识符。
主题别名最大数量由 2 个字节的整形来表示,如果单个报文中该属性出现了多次,则协议错误。若未设定主题别名最大数量,则就将其默认设为 0。
该值用来表示客户端从服务器那里接收到的主题别名的最大数量。客户端使用该值来限制它愿意在此 Connection 上保留的主题别名的数量。 服务器不能在给客户端发送的 PUBLISH 报文中发送超出主题别名最大数量的主题别名[MQTT-3.1.2-26]。当值为 0 时则表示客户端在该连接中不会接收任何主题别名。如果主题别名最大数量不存在或值为 0,则服务器不能发送任何主题别名给客户端[MQTT-3.1.2-27]。
31(0x1F)字节, 原因字符串标识符。
使用 UTF-8 编码字符串来表示响应相关的原因, 该字符串为人类可读和诊断而设计的,并且不应该被客户端解析。
服务器通常用该属性来给客户端提供额外诊断信息。如果增加该属性会使 CONNACK 包的大小超出客户端指定的最大报文大小,则服务器不能发送该属性[MQTT-3.2.2-19]。当同一报文重复包含原因字符串属性时,则会被视为协议错误。
非正式评注
正确使用客户端中的原因字符串的两种方法分别为:客户端代码抛出的异常中使用此信息,或将此字符串写入日志。
38(0x26)字节,用户属性标识符。
由 UTF-9 字符串对表示,该属性可以用来提供额外的信息(包含诊断信息)给客户端。如果增加该属性会使 CONNACK 包的大小超出客户端指定的最大报文大小,则服务器不能发送该属性[MQTT-3.2.2-20]。用户属性可以在单个报文中出现多次,用于表示多个名称,值对。相同的名称也可以出现多次。
该属性的内容和含义不由本规范来定义。包含该属性的 CONNACK 报文的接收者可以忽略它。
40(0x28)字节,通配符订阅可用标识符。
由单个字节的字段来表示。如果存在该属性,则该字节用来声明是否服务器支持通配符订阅,值为 0 表示不支持,值为 1 表示支持,如果没有设定该属性则表示支持,该属性只能出现一次且不能出现 0 或 1 以外的值。如果不存在该属性,那么就支持通配符订阅。该属性在同一报文中如果重复出现,或者发送的值是 0 或 1 以外的值,那么则会被视为协议错误。
如果服务器收到一个包含通配符订阅的 SUBSCRIBE 报文,并且它不支持通配符订阅,那么就会发生协议错误,服务器会如同4.13 节所描述的那样在 DISCONNECT 报文中放一个 0xA2(不支持的通配符订阅)原因码。
如果服务器支持通配符订阅,它仍可以拒绝带有通配符订阅的特定的订阅请求,在这种情况下,服务器可以发送一个带有 0xA2 (不支持的通配符订阅)原因码的 SUBACK 控制报文。
41(0x29)字节,订阅标识符可用标识符。
由单字节的字段来表示,如果存在该属性,该属性是用来表示服务器是否支持订阅标识符。0 表示支持,1 表示不支持,如果不存在该属性,会将其看做支持来处理,若该属性在同一报文中重复出现,则会被视为协议错误,它的值只能是 0 或 1。
如果服务器收到一个包含订阅标识符的 SUBSCRIBE 报文但是该服务器不支持订阅标识符,那么就会将其视为协议错误。服务器会如4.13 节所描述的那样返回一个带有原因码为 0xA1 (订阅标识符不支持)的 DISCONNECT 包。
42(0x2A)字节,共享订阅可用标识符。
由单字节的字段来表示,如果设定了该属性,则该字节表用来表示是否服务器支持共享订阅。其值为 0,意味着不支持共享订阅;其值为 1,意味着支持共享订阅,如果没有设定该属性,默认表示支持。若该属性在同一报文中重复出现,或其值为 0 或 1 以外的数字,则被视为协议错误,
如果服务器接收到的 SUBSCRIBE 报文包含了共享订阅但是服务器却不支持共享订阅,则会被视为协议错误。服务器会按照4.13 节 所描述的那样返回一个带有 0x9E (不支持共享订阅)原因码的 DISCONNECT 报文。
19(0x13)字节,服务器保持连接标识符。
该属性是用 2 个字节整形表示,带有由服务器分配的保持连接时间。如果服务器在 CONNACK 报文中发送了一个服务器保持连接属性,那么客户端必须使用该值而非客户端发送的 CONNECT 报文中的保持连接值[MQTT-3.2.2-21]。如果服务器不发送服务器保持连接属性,那么服务器就必须使用客户端在 CONNECT 包中设置的保持连接值[MQTT-3.2.2-22]。若该属性在同一报文中出现多次,则被视为协议错误。
非正式评注
服务器保持连接的主要用途是让服务器通知客户端,它将断开与客户端的连接,断开时间要早于客户端中指定的保持连接值。
26(0x1A)字节,响应信息标识符。
该属性由一个 UTF-8 编码的字符串表示,是用来创建响应主题的基础。但是客户端如何从响应信息去创建一个响应主题不在本规范中定义。该响应属性在同一报文中重复出现则意味着协议错误。
如果客户端发送了一个值为 1 的请求响应信息,对于服务器而言在不在 CONNACK 中发送响应信息都是可选的。
非正式评注
该属性的一个常见用法是传递主题树的全局唯一部分,该部分至少在其会话的生命周期内为此客户端保留。 这通常不能只是一个随机名称,因为请求客户端和响应客户端都需要被授权来使用它。 将其用作特定客户端的主题树的根是正常的。 要使服务器返回此信息,通常需要正确配置。 此机制允许此配置在服务器中完成任务而非在每个客户端中完成一次。
关于请求/响应的更多信息请参见4.10 节。
28(0x1C)字节,服务器引用的标识符。
该属性由 UTF-8 字符串表示。给客户端用于识别要使用的另外一个服务器。若该属性在同一报文中重复出现,则会被视为协议错误。
正如4.13 节所描述的那样。服务器同时在带有 0x9C (使用另一台服务器)或 0x9D(服务器被移除)原因码的 CONNACK 或 DISCONNECT 报文中使用服务器引用。
相知道更多关于服务器引用如何使用,请参阅4.11 节关于 服务器重定向的信息。
21(0x15)字节,验证方法标识符。
该属性由包含用于扩展验证的扩展方法名的 UTF-8 编码字符串表示,当该属性在同一报文中出现多次时,会被视为协议错误。如果不设置验证方法,默认情况下扩展验证不会被启用。关于扩展验证的更多信息请参阅4.12 节。
22(0x16)字节,验证数据标识符。
该属性是一个包含验证数据的二进制数据块。该数据的内容由验证方法以及已交换的验证数据的状态来定义的。当该属性在同一报文中出现多次时,会被视为协议错误。关于扩展验证的更多信息请参阅4.12 节。
CONNACK 报文没有有效载荷。
最新评论 我的评论
t-io为本站提供HTTP、WebSocket、Socket、页面渲染与压缩等服务,nginx为本站提供反向代理服务
© 2017-2023 钛特云 版权所有 | 浙ICP备17032976号 | 浙公网安备 33011802002129号