热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

mqtt中clientid怎么查_MQTT协议之连接

奇技指南在之前的《初识MQTT协议》中已简单介绍了MQTT协议报文的格式,本篇文章将对集中的连接协议进行详细的介绍,以及自己对该协议的一些思考和理解。本

奇技指南

在之前的《初识MQTT协议》中已简单介绍了MQTT协议报文的格式,本篇文章将对集中的连接协议进行详细的介绍,以及自己对该协议的一些思考和理解。

本文首发于HULK一线技术杂谈。

1

CONNECT

客户端和服务端建立连接之后,发送的第一个报文必须是CONNECT。客户端只能发送一次CONNECT报文,如果服务端收到了第二个CONNECT报文,必须将其视为错误,并且断开连接。

协议格式

固定报头

19a0956107123de41286e7093a604b9a.png

可变报头

可变报头分为四个部分,分别是协议名称(Protocol Name),协议级别(Protocol Level),连接标志(Connect Flags),保持连接(Keep Alive)。

协议名称

44a2310441eb77bced39d840e6fe48b6.png

1. 协议名是MQTT的UTF-8编码的字符串。MQTT规范的后续版本不会改变这个字符串的偏移和长度。

2. 如果协议不正确服务端断开连接。(MQTT 3.1.1)其他规范中可以有其他规范。

3. 数据包检测工具,可以使用协议名来识别MQTT流量。

协议级别

6822c30cd36e972c6107a42f21ff253c.png

1. 使用8位来表示协议的修订版本级别。MQTT3.1.1的协议级别为4。这个也是MQTT5的由来,MQTT5的协议级别为5,故称为MQTT5。

2. 服务端收到一个自己不支持的协议级别的时候,必须返回一个returnCode为0x01的CONNACK的报文给客户端,随后服务端断开相应的连接。

    连接标志

209fe7d435d23e38c59603081f3120a4.png

3. 服务端必须校验连接标志中的预留字段是否为0,如果不为0,必须断开该连接。

4. 清理会话标志

  A. 清理会话标志的表现

    a.清理会话标志为0(false)

      i.如果已存在相同ClientId的会话,则必须恢复相应的会话。

      ii.不存在相同ClientId的会话,则重新创建一个新的会话。

      iii.客户端和服务端断开连接后,服务端必须保存相应的会话信息。

      iv.连接断开后,服务端必须保留该Session所有的订阅Topic的Qos1和Qos2的消息。服务端也可以保留Qos0的消息,此为可选项。

    b.清理会话标志1(true) 客户端和服务端都必须丢弃之前的会话并且重新创建一个会话。会话信息是和连接绑定的,该会话相关的数据,不能被后续的会话使用

  B. 状态信息

    a. 客户端

      i.Qos和Qos2已经发送到服务端,但是还没有完全结束的消息。

      ii.Qos2已经收到的消息,但是还没有最终完成的消息。

    b. 服务端

      i.会话存在的信息,即时会话的其他内容都是空的。

      ii.客户端的订阅信息。

      iii.Qos1和Qos2已经发送到客户端但是没有完全结束的消息。

      iv.Qos2已经收到的,但是还没有最终结束的消息。

      v.等待发送给客户端的Qos1和Qos2消息。

      vi.可选的等待发送给客户端的Qos0的消息。

  C. 注意事项

    a. 保留消息不是服务端会话状态的一部分,会话中止时不能删除。

    b. 清理会话设置为1时,客户端和服务端的状态删除不需要是原子操作。 

    c. 如果希望保证在异常时的状态一致性,可以通过清理会话标志始终设置为1直到成功连接上服务。

5. 遗嘱标志 遗嘱标志设置了(1或者true)之后,连接建立成功之后,遗嘱消息会被存储在服务端并且和这个网络连接绑定,当该网络连接异常关闭时,服务端必须发布这个遗嘱消息,除非客户端发送了DISCONNECT消息后,服务端删除了该消息。

  A. 遗嘱消息发布的条件,包括但不限于

    a. 服务端检测到IO错误或者网络故障。

    b. 客户端在保持连接的时间内未能通讯。

    c. 客户端没有先发送DISCONNECT报文而直接关闭了连接。

    d. 由于协议错误服务端关闭了网络连接。

  B. 注意事项

    a. 遗嘱标志设置后,Will Qos和Will Retain会被用到,有效载荷必需包含Will Topic和Will Message。

    b. 被发布或收到客户端的DISCONNECT报文之后,遗嘱消息必须从存储中删除。

    c. 遗嘱标志设置为0时,Will Qos和Will Retain字段必须设置为0,并且有效载荷中不能包含Will Topic和Will Message.

    d. 服务端应该迅速发布遗嘱消息。在关机或者故障的情况下,服务端可以推迟发布消息到服务恢复。

6. 遗嘱消息Qos 遗嘱消息的QOS。

7. 遗嘱预留消息 遗嘱消息的保留标志。

8. 用户名标志 表示是否又用户名在有效载荷中。

9. 密码标志 表示是否又密码在有效载荷中,如果用户名标志为0,该字段也必须为0。

    保持连接

0752c18c4bf6205381d1940f0f680636.png

10. 保持连接单位为秒(s),两个Byte 16位表示,所以最长的keepAlive的时间为18小时12分15秒。

11. 表示的是客户端从发送完一个报文到发送下一个报文,两者之间允许的最大时间间隔。客户端负责保证控制报文发送的时间间隔不超过保持连接的值,如果没有其他的报文可以发送,客户端必须发送PINGREQ报文。

12. 客户端可以随时发送PINGREQ报文,并且根绝PINGRESP的报文判断和服务端的活动状态。

13. 如果服务端在1.5倍的保持连接(非0)时间内没有收到任何的报文,服务端必须断开相应的连接。

14. 客户端发送PINGREQ之后,在规定的时间没有收到服务端的PINGRESP报文的回应,客户端应该断开该连接。

15. 保持连接设置为0表示关闭保持连接的功能。服务端不需要因为客户端的不活跃而断开连接。

16. 服务端主要认为客户端是不活跃或者无响应的,都可以断开客户端连接。

有效载荷

有效载荷中的字段包含一个或者多个是根据可变报头中的标志来决定有无的。如果存在的话,必须按照如下的顺序,ClientId, Will Topic, Will Message, User Name, Password。

1. ClientId

   A. 每个客户端连接服务端必须有一个唯一的ClientId标志。该标志是客户端和服务端用来区分会话的唯一标志。

   B. 必须提供并且必须是CONNECT报文有效负载的第一个字段。

   C. 必须[1-23]的UTF-8编码,包含的内容必须是[0-9][a-z][A-Z]。服务端也可以支持更长的以及其他的UTF-8字符。

   D. 如果ClientId是0字节的,服务端必须为其赋予一个唯一的标志,然后进行后续的处理。ClientId为0字节时有如下的限制,

      a. 清理会话标志必须设置为1,否则服务端返回returnCode=0x02的CONNACK,并且关闭该网络连接。

   E. 服务端如果拒绝该ClientId,服务端必须返回returnCode=0x02的CONNACK,并且关闭该网络连接。

2. Will Topic 遗嘱消息的topic,必须是UTF-8编码的字符串。

3. Will Message 遗嘱消息的内容。

4. User Name 用户名,必须是UTF-8的字符串。

5. Passowrd

46a4f1e7944514b0460731892325a56b.png

由两个Byte表示的二进制数据标识。最长可以为65535Bytes的二进制。

响应

    检验

1. 网络建立后,服务端在指定时间内没有收到客户端的CONNECT消息,服务端应该关闭连接。

2. 服务端必须按照以上规范来验证CONNECT报文,如果不符合规范,服务端必须关闭连接,而且不需要发送CONNACK。

3. 服务端可以检查CONNECT的内容,如果任何一个检查没有通过,应该返回一个指定的CONNACK的报文,并且必须关闭该连接。

    服务端检验通过后的处理

4. 如果又相同ClientId的连接,服务端必须关闭已有的连接。

5. 服务端需要处理和清理会话相关的内容。

6. 返回客户端CONNACK。

7. 开始消息投递和保活监控。 备注:客户端可以不等待CONNACK的返回,直接发送其他的控制报文,如果服务端拒绝了相应的连接,服务端必须不处理CONNECT报文之后的任何协议。

    CONNACK
    服务端返回给客户端的第一个协议必须是CONNACK报文。

    协议格式

    固定报头

6ab135bb0eac29c43053124424c7a8a2.png

    固定报头中只有报文类型为2。

    可变报头

fc3a82e2f4955bfc402334d569338901.png

    可变报头包含连接确认标志和连接返回码。

    连接确认标志

8. 保留位必须为0

9. 当前会话SP 

    A. 服务端如果没有之前的会话时,该值为0。

    B. 如果returnCode=0(连接被接收),服务端存在之前的会话,该值为1。

    C. 该标志能够是客户端和服务端是否又已存在会话保持一致,如果两者不一致,客户端可以选择断开连接或者继续连接。客户端可以通过断开连接,清理会话设置为1,再次连接,然后再次断开连接的方式来丢弃客户端和服务端的会话状态。

    D. 如果返回码非0,会话状态必须为0。

     连接返回码

b711e3140861f9965c8ab0060d7dc138.png     有效载荷

     CONNACK报文没有有效载荷字段。

2

总结

1. 连接报文是MQTT连接建立之后的第一个报文,如果不是将会断开连接,并且连接报文也只能发送一次。

2. 清理会话的设置也是通过连接报文进行设置,可以通过重新连接,设置清理会话的标志来保持客户端和服务端的会话信息。

3. 遗言是跟连接绑定的,在用户非正常DISCONNECT的情况下将触发遗言的发布。

4. 保持连接是检测客户端发送到服务端的消息的间隔时间,协议固定在1.5倍的保持连接的时间,会断开连接。现在使用的EMQ的保持连接的机制,KeepAlive * backoff = CheckTime,从客户端建立连接开始进行循环检测,连续两次没有检测到Socket报文的话,则认为超时,故真实的超时时间为CheckTime * 2

界世的你当不

只作你的肩膀

ae7b1692ccd7c0cc8e06b9704458677a.png4a4a8b842314755a20b2ae3c0314f21a.png

 360官方技术公众号 

技术干货|一手资讯|精彩活动

空·




推荐阅读
  • 1、etcnginxconf.ddefault.conf,添加如下信息:location{try_files$uri$urirouter;rootho ... [详细]
  • 本文介绍了解决Netty拆包粘包问题的一种方法——使用特殊结束符。在通讯过程中,客户端和服务器协商定义一个特殊的分隔符号,只要没有发送分隔符号,就代表一条数据没有结束。文章还提供了服务端的示例代码。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 关于我们EMQ是一家全球领先的开源物联网基础设施软件供应商,服务新产业周期的IoT&5G、边缘计算与云计算市场,交付全球领先的开源物联网消息服务器和流处理数据 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • web.py开发web 第八章 Formalchemy 服务端验证方法
    本文介绍了在web.py开发中使用Formalchemy进行服务端表单数据验证的方法。以User表单为例,详细说明了对各字段的验证要求,包括必填、长度限制、唯一性等。同时介绍了如何自定义验证方法来实现验证唯一性和两个密码是否相等的功能。该文提供了相关代码示例。 ... [详细]
  • 移动端常用单位——rem的使用方法和注意事项
    本文介绍了移动端常用的单位rem的使用方法和注意事项,包括px、%、em、vw、vh等其他常用单位的比较。同时还介绍了如何通过JS获取视口宽度并动态调整rem的值,以适应不同设备的屏幕大小。此外,还提到了rem目前在移动端的主流地位。 ... [详细]
  • 图像因存在错误而无法显示 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • 如何在HTML中获取鼠标的当前位置
    本文介绍了在HTML中获取鼠标当前位置的三种方法,分别是相对于屏幕的位置、相对于窗口的位置以及考虑了页面滚动因素的位置。通过这些方法可以准确获取鼠标的坐标信息。 ... [详细]
  • 超级简单加解密工具的方案和功能
    本文介绍了一个超级简单的加解密工具的方案和功能。该工具可以读取文件头,并根据特定长度进行加密,加密后将加密部分写入源文件。同时,该工具也支持解密操作。加密和解密过程是可逆的。本文还提到了一些相关的功能和使用方法,并给出了Python代码示例。 ... [详细]
  • 指示|厂家_UDS协议
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了UDS协议相关的知识,希望对你有一定的参考价值。UDS的第二类诊断服务,数据传输 ... [详细]
  • 五、RabbitMQ Java Client基本使用详解
    JavaClient的5.x版本系列需要JDK8,用于编译和运行。在Android上,仅支持Android7.0或更高版本。4.x版本系列支持7.0之前 ... [详细]
  • 在单位的一台4cpu的服务器上部署了esxserver,挂载了6个虚拟机,目前运行正常。在安装部署过程中,得到了cnvz.net论坛精华区 ... [详细]
  • 浅析对象 VO、DTO、DO、PO 概念
    作者|CatQi链接|cnblogs.comqixuejiap4390086.html前言由于此订阅号换了个皮肤,导致用户接受文章不及时。读者可以打开订阅号「Web项 ... [详细]
author-avatar
JKNx2602931435
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有