• [问题求助] MQTT QoS 0,1,2 我应该如何选择,我的场景是大规模物联设备(点位在3000左右,5秒传输一次)传感器传输温度、湿度
    MQTT QoS 0,1,2 我应该如何选择,我的场景是大规模物联设备(点位在3000左右,5秒传输一次)传感器传输温度、湿度
  • [技术干货] 实现web实时消息推送的方案--MQTT
    什么是 MQTT协议?MQTT 全称(Message Queue Telemetry Transport):一种基于发布/订阅(publish/subscribe)模式的轻量级通讯协议,通过订阅相应的主题来获取消息,是物联网(Internet of Thing)中的一个标准传输协议。该协议将消息的发布者(publisher)与订阅者(subscriber)进行分离,因此可以在不可靠的网络环境中,为远程连接的设备提供可靠的消息服务,使用方式与传统的MQ有点类似。TCP协议位于传输层,MQTT 协议位于应用层,MQTT 协议构建于TCP/IP协议上,也就是说只要支持TCP/IP协议栈的地方,都可以使用MQTT协议。为什么要用 MQTT协议?MQTT协议为什么在物联网(IOT)中如此受偏爱?而不是其它协议,比如我们更为熟悉的 HTTP协议呢?首先HTTP协议它是一种同步协议,客户端请求后需要等待服务器的响应。而在物联网(IOT)环境中,设备会很受制于环境的影响,比如带宽低、网络延迟高、网络通信不稳定等,显然异步消息协议更为适合IOT应用程序。HTTP是单向的,如果要获取消息客户端必须发起连接,而在物联网(IOT)应用程序中,设备或传感器往往都是客户端,这意味着它们无法被动地接收来自网络的命令。通常需要将一条命令或者消息,发送到网络上的所有设备上。HTTP要实现这样的功能不但很困难,而且成本极高。具体的MQTT协议介绍和实践,这里我就不再赘述了,大家可以参考我之前的两篇文章,里边写的也都很详细了。MQTT协议的介绍我也没想到 springboot + rabbitmq 做智能家居,会这么简单MQTT实现消息推送未读消息(小红点),前端 与 RabbitMQ 实时消息推送实践,贼简单~Websocketwebsocket应该是大家都比较熟悉的一种实现消息推送的方式,上边我们在讲SSE的时候也和websocket进行过比较。WebSocket是一种在TCP连接上进行全双工通信的协议,建立客户端和服务器之间的通信渠道。浏览器和服务器仅需一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。springboot整合websocket,先引入websocket相关的工具包,和SSE相比额外的开发成本<!-- 引入websocket --><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId></dependency>服务端使用@ServerEndpoint注解标注当前类为一个websocket服务器,客户端可以通过ws://localhost:7777/webSocket/10086来连接到WebSocket服务器端@Component@Slf4j@ServerEndpoint("/websocket/{userId}")public class WebSocketServer { //与某个客户端的连接会话,需要通过它来给客户端发送数据 private Session session; private static final CopyOnWriteArraySet<WebSocketServer> webSockets = new CopyOnWriteArraySet<>(); // 用来存在线连接数 private static final Map<String, Session> sessionPool = new HashMap<String, Session>(); /** * 公众号:程序员小富 * 链接成功调用的方法 */ @OnOpen public void onOpen(Session session, @PathParam(value = "userId") String userId) { try { this.session = session; webSockets.add(this); sessionPool.put(userId, session); log.info("websocket消息: 有新的连接,总数为:" + webSockets.size()); } catch (Exception e) { } } /** * 公众号:程序员小富 * 收到客户端消息后调用的方法 */ @OnMessage public void onMessage(String message) { log.info("websocket消息: 收到客户端消息:" + message); } /** * 公众号:程序员小富 * 此为单点消息 */ public void sendOneMessage(String userId, String message) { Session session = sessionPool.get(userId); if (session != null && session.isOpen()) { try { log.info("websocket消: 单点消息:" + message); session.getAsyncRemote().sendText(message); } catch (Exception e) { e.printStackTrace(); } } }}前端初始化打开WebSocket连接,并监听连接状态,接收服务端数据或向服务端发送数据。<script> var ws = new WebSocket('ws://localhost:7777/webSocket/10086'); // 获取连接状态 console.log('ws连接状态:' + ws.readyState); //监听是否连接成功 ws.onopen = function () { console.log('ws连接状态:' + ws.readyState); //连接成功则发送一个数据 ws.send('test1'); } // 接听服务器发回的信息并处理展示 ws.onmessage = function (data) { console.log('接收到来自服务器的消息:'); console.log(data); //完成通信后关闭WebSocket连接 ws.close(); } // 监听连接关闭事件 ws.onclose = function () { // 监听整个过程中websocket的状态 console.log('ws连接状态:' + ws.readyState); } // 监听并处理error事件 ws.onerror = function (error) { console.log(error); } function sendMessage() { var content = $("#message").val(); $.ajax({ url: '/socket/publish?userId=10086&message=' + content, type: 'GET', data: { "id": "7777", "content": content }, success: function (data) { console.log(data) } }) }</script>页面初始化建立websocket连接,之后就可以进行双向通信了,效果还不错转载自https://www.studyjava.cn/post/2004
  • [问题求助] 各位专家是否有使用java做mqtt服务器的指导案例,想让小熊派的数据上报上来并且展示
    各位专家是否有使用java做mqtt服务器的指导案例,想让小熊派的数据上报上来并且展示
  • [问题求助] mqtts加密的这个结构体数据应该怎么填啊?
    这个结构体前面这几个uint8_t是干什么的?应该怎么填啊?
  • [技术干货] MQTT报文格式(第三篇)
    上一篇博客地址:MQTT报文格式(第二篇)_IoT物联网_华为云论坛 (huaweicloud.com)三、有效载荷Payload某些MQTT控制报文在报文的最后部分包含一个有效载荷,这将在第三章论述。对于PUBLISH来说有效载荷就是应用消息。下表列出了需要有效载荷的控制报文。包含有效载荷的控制报文 Control Packets that contain a Payload控制报文有效载荷CONNECT需要CONNACK不需要PUBLISH可选PUBACK不需要PUBREC不需要PUBREL不需要PUBCOMP不需要SUBSCRIBE需要SUBACK需要UNSUBSCRIBE需要UNSUBACK不需要PINGREQ不需要PINGRESP不需要DISCONNECT不需要以上就是MQTT全部的报文格式,总共用了三篇文章对MQTT报文格式的细节方面进行分析,希望能对深入理解MQTT协议的人有所帮助。下面是MQTT各版本的规范声明:声明序号规范声明[MQTT-1.5.3-1]UTF-8编码字符串中的字符数据必须是按照Unicode规范 [Unicode] 定义的和在RFC3629 [RFC3629] 中重申的有效的UTF-8格式。特别需要指出的是,这些数据不能包含字符码在U+D800和U+DFFF之间的数据。如果服务端或客户端收到了一个包含无效UTF-8字符的控制报文,它必须关闭网络连接。[MQTT-1.5.3-2]UTF-8编码的字符串不能包含空字符U+0000。如果客户端或服务端收到了一个包含U+0000的控制报文,它必须关闭网络连接。[MQTT-1.5.3-3]UTF-8编码序列0XEF 0xBB 0xBF总是被解释为U+FEFF(零宽度非换行空白字符),无论它出现在字符串的什么位置,报文接收者都不能跳过或者剥离它。[MQTT-2.2.2-1]表格 2.2中任何标记为“保留”的标志位,都是保留给以后使用的,必须设置为表格中列出的值。[MQTT-2.2.2-2]如果收到非法的标志,接收者必须关闭网络连接。[MQTT-2.3.1-1]SUBSCRIBE,UNSUBSCRIBE和PUBLISH(QoS大于0)控制报文必须包含一个非零的16位报文标识符(Packet Identifier。[MQTT-2.3.1-2]客户端每次发送一个新的这些类型的报文时都必须分配一个当前未使用的报文标识符。[MQTT-2.3.1-3]如果一个客户端要重发这个特殊的控制报文,在随后重发那个报文时,它必须使用相同的标识符。当客户端处理完这个报文对应的确认后,这个报文标识符就释放可重用。QoS 1的PUBLISH对应的是PUBACK,QoS 2的PUBLISH对应的是PUBCOMP,与SUBSCRIBE或UNSUBSCRIBE对应的分别是SUBACK或UNSUBACK[MQTT-2.3.1-4]发送一个QoS 0的PUBLISH报文时,相同的条件也适用于服务端。[MQTT-2.3.1-5]QoS设置为0的PUBLISH报文不能包含报文标识符。[MQTT-2.3.1-6]PUBACK, PUBREC, PUBREL报文必须包含与最初发送的PUBLISH报文相同的报文标识符。[MQTT-2.3.1-7]与 [MQTT-2.3.1-6] 类似,SUBACK和UNSUBACK必须包含在对应的SUBSCRIBE和UNSUBSCRIBE报文中使用的报文标识符。[MQTT-3.1.0-1]客户端到服务端的网络连接建立后,客户端发送给服务端的第一个报文必须是CONNECT报文。[MQTT-3.1.0-2]在一个网络连接上,客户端只能发送一次CONNECT报文。服务端必须将客户端发送的第二个CONNECT报文当作协议违规处理并断开客户端的连接。[MQTT-3.1.2-1]如果协议名不正确服务端可以断开客户端的连接,也可以按照某些其它规范继续处理CONNECT报文。对于后一种情况,按照本规范,服务端不能继续处理CONNECT报文。[MQTT-3.1.2-2]如果发现不支持的协议级别,服务端必须给发送一个返回码为0x01(不支持的协议级别)的CONNACK报文响应CONNECT报文,然后断开客户端的连接。[MQTT-3.1.2-3]服务端必须验证CONNECT控制报文的保留标志位(第0位)是否为0,如果不为0必须断开客户端连接。[MQTT-3.1.2-4]如果清理会话(CleanSession)标志被设置为0,服务端必须基于当前会话(使用客户端标识符识别)的状态恢复与客户端的通信。如果没有与这个客户端标识符关联的会话,服务端必须创建一个新的会话。在连接断开之后,当连接断开后,客户端和服务端必须保存会话信息。[MQTT-3.1.2-5]当清理会话标志为0的会话连接断开之后,服务端必须将之后的QoS 1和QoS 2级别的消息保存为会话状态的一部分,如果这些消息匹配断开连接时客户端的任何订阅。[MQTT-3.1.2-6]如果清理会话(CleanSession)标志被设置为1,客户端和服务端必须丢弃之前的任何会话并开始一个新的会话。会话仅持续和网络连接同样长的时间。与这个会话关联的状态数据不能被任何之后的会话重用。[MQTT-3.1.2.7]保留消息不是服务端会话状态的一部分,会话终止时不能删除保留消息。[MQTT-3.1.2-8]遗嘱标志(Will Flag)被设置为1,表示如果连接请求被接受了,遗嘱(Will Message)消息必须被存储在服务端并且与这个网络连接关联。之后网络连接关闭时,服务端必须发布这个遗嘱消息,除非服务端收到DISCONNECT报文时删除了这个遗嘱消息。[MQTT-3.1.2-9]如果遗嘱标志被设置为1,连接标志中的Will QoS和Will Retain字段会被服务端用到,同时有效载荷中必须包含Will Topic和Will Message字段。[MQTT-3.1.2-10]一旦被发布或者服务端收到了客户端发送的DISCONNECT报文,遗嘱消息就必须从存储的会话状态中移除。[MQTT-3.1.2-11]如果遗嘱标志被设置为0,连接标志中的Will QoS和Will Retain字段必须设置为0,并且有效载荷中不能包含Will Topic和Will Message字段。[MQTT-3.1.2-12]如果遗嘱标志被设置为0,网络连接断开时,不能发送遗嘱消息。.[MQTT-3.1.2-13]如果遗嘱标志被设置为0,遗嘱QoS也必须设置为0(0x00)。[MQTT-3.1.2-14]如果遗嘱标志被设置为1,遗嘱QoS的值可以等于0(0x00),1(0x01),2(0x02)。它的值不能等于3。[MQTT-3.1.2-15]如果遗嘱标志被设置为0,遗嘱保留(Will Retain)标志也必须设置为0。[MQTT-3.1.2-16]如果遗嘱保留被设置为0,服务端必须将遗嘱消息当作非保留消息发布。[MQTT-3.1.2-17]如果遗嘱保留被设置为1,服务端必须将遗嘱消息当作保留消息发布。[MQTT-3.1.2-18]如果用户名(User Name)标志被设置为0,有效载荷中不能包含用户名字段。[MQTT-3.1.2-19]如果用户名(User Name)标志被设置为1,有效载荷中必须包含用户名字段。[MQTT-3.1.2-20]如果密码(Password)标志被设置为0,有效载荷中不能包含密码字段。[MQTT-3.1.2-21]如果密码(Password)标志被设置为1,有效载荷中必须包含密码字段[MQTT-3.1.2-22]如果用户名标志被设置为0,密码标志也必须设置为0。[MQTT-3.1.2-23]客户端负责保证控制报文发送的时间间隔不超过保持连接的值。如果没有任何其它的控制报文可以发送,客户端必须发送一个PINGREQ报文。[MQTT-3.1.2-24]如果保持连接的值非零,并且服务端在一点五倍的保持连接时间内没有收到客户端的控制报文,它必须断开客户端的网络连接,认为网络连接已断开。[MQTT-3.1.3-1]如果包含的话,必须按这个顺序出现:客户端标识符,遗嘱主题,遗嘱消息,用户名,密码。[MQTT-3.1.3-2]服务端使用客户端标识符 (ClientId) 识别客户端。连接服务端的每个客户端都有唯一的客户端标识符(ClientId)。客户端和服务端都必须使用ClientId识别两者之间的MQTT会话相关的状态。[MQTT-3.1.3-3]客户端标识符 (ClientId) 必须存在而且必须是CONNECT报文有效载荷的第一个字段。[MQTT-3.1.3-4]客户端标识符必须是1.5.3节定义的UTF-8编码字符串。[MQTT-3.1.3-5]服务端必须允许1到23个字节长的UTF-8编码的客户端标识符,客户端标识符只能包含这些字符:“0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ”(大写字母,小写字母和数字)。[MQTT-3.1.3-6]服务端可以允许客户端提供一个零字节的客户端标识符 (ClientId) ,如果这样做了,服务端必须将这看作特殊情况并分配唯一的客户端标识符给那个客户端。然后它必须假设客户端提供了那个唯一的客户端标识符,正常处理这个CONNECT报文。[MQTT-3.1.3-7]如果客户端提供了一个零字节的客户端标识符,它必须同时将清理会话标志设置为1。[MQTT-3.1.3-8]如果客户端提供的ClientId为零字节且清理会话标志为0,服务端必须发送返回码为0x02(表示标识符不合格)的CONNACK报文响应客户端的CONNECT报文,然后关闭网络连接。[MQTT-3.1.3-9]如果服务端拒绝了这个ClientId,它必须发送返回码为0x02(表示标识符不合格)的CONNACK报文响应客户端的CONNECT报文,然后关闭网络连接。[MQTT-3.1.3-10]遗嘱主题必须是 1.5.3节定义的UTF-8编码字符串。[MQTT-3.1.3-11]用户名必须是 1.5.3节定义的UTF-8编码字符串。[MQTT-3.1.4-1]服务端必须按照3.1节的要求验证CONNECT报文,如果报文不符合规范,服务端不发送CONNACK报文直接关闭网络连接。[MQTT-3.1.4-2]如果ClientId表明客户端已经连接到这个服务端,那么服务端必须断开原有的客户端连接。[MQTT-3.1.4-3]服务端必须按照 3.1.2.4节的描述执行清理会话的过程。[MQTT-3.1.4-4]服务端必须发送返回码为零的CONNACK报文作为CONNECT报文的确认响应。[MQTT-3.1.4-5]如果服务端拒绝了CONNECT,它不能处理客户端在CONNECT报文之后发送的任何数据。[MQTT-3.2.0-1]服务端发送CONNACK报文响应从客户端收到的CONNECT报文。服务端发送给客户端的第一个报文必须是CONNACK。[MQTT-3.2.2-1]如果服务端收到清理会话(CleanSession)标志为1的连接,除了将CONNACK报文中的返回码设置为0之外,还必须将CONNACK报文中的当前会话设置(Session Present)标志为0。[MQTT-3.2.2-2]如果服务端收到一个CleanSession为0的连接,当前会话标志的值取决于服务端是否已经保存了ClientId对应客户端的会话状态。如果服务端已经保存了会话状态,它必须将CONNACK报文中的当前会话标志设置为1。[MQTT-3.2.2-3]如果服务端没有已保存的会话状态,它必须将CONNACK报文中的当前会话设置为0。还需要将CONNACK报文中的返回码设置为0。[MQTT-3.2.2-4]如果服务端发送了一个包含非零返回码的CONNACK报文,它必须将当前会话标志设置为0。[MQTT-3.2.2-5]如果服务端发送了一个包含非零返回码的CONNACK报文,那么它必须关闭网络连接。.[MQTT-3.2.2-6]如果认为上表格3.1中的所有连接返回码都不太合适,那么服务端必须关闭网络连接,不需要发送CONNACK报文。[MQTT-3.3.1-1]客户端或服务端请求重发一个PUBLISH报文时,必须将DUP标志设置为1。[MQTT-3.3.1-2]对于QoS 0的消息,DUP标志必须设置为0[MQTT-3.3.1-3]服务端发送PUBLISH报文给订阅者时,收到(入站)的PUBLISH报文的DUP标志的值不会被传播。发送(出站)的PUBLISH报文与收到(入站)的PUBLISH报文中的DUP标志是独立设置的,它的值必须单独的根据发送(出站)的PUBLISH报文是否是一个重发来确定。[MQTT-3.3.1-4]PUBLISH报文不能将QoS所有的位设置为1。如果服务端或客户端收到QoS所有位都为1的PUBLISH报文,它必须关闭网络连接。[MQTT-3.3.1-5]如果客户端发给服务端的PUBLISH报文的保留(RETAIN)标志被设置为1,服务端必须存储这个应用消息和它的服务质量等级(QoS),以便它可以被分发给未来的主题名匹配的订阅者。[MQTT-3.3.1-6]一个新的订阅建立时,对每个匹配的主题名,如果存在最近保留的消息,它必须被发送给这个订阅者。[MQTT-3.3.1-7]如果服务端收到一条保留(RETAIN)标志为1的QoS 0消息,它必须丢弃之前为那个主题保留的任何消息。它应该将这个新的QoS 0消息当作那个主题的新保留消息,但是任何时候都可以选择丢弃它 — 如果这种情况发生了,那个主题将没有保留消息。[MQTT-3.3.1-8]服务端发送PUBLISH报文给客户端时,如果消息是作为客户端一个新订阅的结果发送,它必须将报文的保留标志设为1。[MQTT-3.3.1-9]当一个PUBLISH报文发送给客户端是因为匹配一个已建立的订阅时,服务端必须将保留标志设为0,不管它收到的这个消息中保留标志的值是多少。[MQTT-3.3.1-10]保留标志为1且有效载荷为零字节的PUBLISH报文会被服务端当作正常消息处理,它会被发送给订阅主题匹配的客户端。此外,同一个主题下任何现存的保留消息必须被移除,因此这个主题之后的任何订阅者都不会收到一个保留消息。[MQTT-3.3.1-11]服务端不能存储零字节的保留消息。[MQTT-3.3.1-12]如果客户端发给服务端的PUBLISH报文的保留标志位0,服务端不能存储这个消息也不能移除或替换任何现存的保留消息。[MQTT-3.3.2-1]主题名必须是PUBLISH报文可变报头的第一个字段。它必须是 1.5.3节定义的UTF-8编码的字符串。[MQTT-3.3.2-2]PUBLISH报文中的主题名不能包含通配符。[MQTT-3.3.2-3]服务端发送给订阅客户端的PUBLISH报文的主题名必须匹配该订阅的主题过滤器(根据 4.7节定义的匹配过程)。[MQTT-3.3.4-1]PUBLISH报文的接收者必须按照根据PUBLISH报文中的QoS等级发送响应,见表格3.4的描述。[MQTT-3.3.5-1]服务端必须将消息分发给所有订阅匹配的QoS等级最高的客户端。[MQTT-3.3.5-2]如果服务端实现不授权某个客户端发布PUBLISH报文,它没有办法通知那个客户端。它必须按照正常的QoS规则发送一个正面的确认,或者关闭网络连接。[MQTT-3.6.1-1]PUBREL控制报文固定报头的第3,2,1,0位是保留位,必须被设置为0,0,1,0。服务端必须将其它的任何值都当做是不合法的并关闭网络连接。[MQTT-3.8.1-1]SUBSCRIBE控制报固定报头的第3,2,1,0位是保留位,必须分别设置为0,0,1,0。服务端必须将其它的任何值都当做是不合法的并关闭网络连接。[MQTT-3.8.3-1]SUBSCRIBE报文有效载荷中的主题过滤器列表必须是1.5.3节定义的UTF-8字符串。[MQTT-3.8.3-2]如果服务端选择不支持包含通配符的主题过滤器,必须拒绝任何包含通配符过滤器的订阅请求。[MQTT-3.8.3-3]SUBSCRIBE报文的有效载荷必须包含至少一对主题过滤器 和 QoS等级字段组合。没有有效载荷的SUBSCRIBE报文是违反协议的。[MQTT-3-8.3-4]如果有效载荷中的任何位是非零值,或者QoS不等于0,1或2,服务端必须认为SUBSCRIBE报文是不合法的并关闭网络连接。[MQTT-3.8.4-1]服务端收到客户端发送的一个SUBSCRIBE报文时,必须使用SUBACK报文响应。[MQTT-3.8.4-2]SUBACK报文必须和等待确认的SUBSCRIBE报文有相同的报文标识符。[MQTT-3.8.4-3]如果服务端收到一个SUBSCRIBE报文,报文的主题过滤器与一个现存订阅的主题过滤器相同,那么必须使用新的订阅彻底替换现存的订阅。新订阅的主题过滤器和之前订阅的相同,但是它的最大QoS值可以不同。与这个主题过滤器匹配的任何现存的保留消息必须被重发,但是发布流程不能中断。[MQTT-3.8.4-4]如果服务端收到包含多个主题过滤器的SUBSCRIBE报文,它必须如同收到了一系列的多个SUBSCRIBE报文一样处理那个,除了需要将它们的响应合并到一个单独的SUBACK报文发送。[MQTT-3.8.4-5]服务端发送给客户端的SUBACK报文对每一对主题过滤器 和QoS等级都必须包含一个返回码。这个返回码必须表示那个订阅被授予的最大QoS等级,或者表示这个订阅失败。[MQTT-3.8.4-6]服务端可以授予比订阅者要求的低一些的QoS等级。为响应订阅而发出的消息的有效载荷的QoS必须是原始发布消息的QoS和服务端授予的QoS两者中的最小值。如果原始消息的QoS是1而被授予的最大QoS是0,允许服务端重复发送一个消息的副本给订阅者。[MQTT-3.9.3-1]返回码的顺序必须和SUBSCRIBE报文中主题过滤器的顺序相同。[MQTT-3.9.3-2]0x00, 0x01, 0x02, 0x80之外的SUBACK返回码是保留的,不能使用。[MQTT-3.10.1-1]UNSUBSCRIBE报文固定报头的第3,2,1,0位是保留位且必须分别设置为0,0,1,0。服务端必须认为任何其它的值都是不合法的并关闭网络连接。[MQTT-3.10.3-1]UNSUBSCRIBE报文中的主题过滤器必须是连续打包的、按照1.5.3节定义的UTF-8编码字符串。[MQTT-3.10.3-2]UNSUBSCRIBE报文的有效载荷必须至少包含一个消息过滤器。没有有效载荷的UNSUBSCRIBE报文是违反协议的。[MQTT-3.10.4-1]UNSUBSCRIBE报文提供的主题过滤器(无论是否包含通配符)必须与服务端持有的这个客户端的当前主题过滤器集合逐个字符比较。如果有任何过滤器完全匹配,那么它(服务端)自己的订阅将被删除,否则不会有进一步的处理。[MQTT-3.10.4-2]如果服务端删除了一个订阅,它必须停止分发任何新消息给这个客户端。[MQTT-3.10.4-3]如果服务端删除了一个订阅,它必须完成分发任何已经开始往客户端发送的QoS 1和QoS 2的消息。[MQTT-3.10.4-4]服务端必须发送UNSUBACK报文响应客户端的UNSUBSCRIBE请求。UNSUBACK报文必须包含和UNSUBSCRIBE报文相同的报文标识符。[MQTT-3.10.4-5]即使没有删除任何主题订阅,服务端也必须发送一个SUBACK响应。[MQTT-3.10.4-6]如果服务端收到包含多个主题过滤器的UNSUBSCRIBE报文,它必须如同收到了一系列的多个UNSUBSCRIBE报文一样处理那个报文,除了将它们的响应合并到一个单独的UNSUBACK报文外。[MQTT-3.12.4-1]服务端必须发送 PINGRESP报文响应客户端的PINGREQ报文。[MQTT-3.14.1-1]服务端必须验证所有的保留位都被设置为0,如果它们不为0必须断开连接。[MQTT-3.14.4-1]客户端发送DISCONNECT报文之后,必须关闭网络连接。[MQTT-3.14.4-2]客户端发送DISCONNECT报文之后,不能通过那个网络连接再发送任何控制报文。[MQTT-3.14.4-3]服务端收到DISCONNECT报文时,必须丢弃任何与当前连接关联的未发布的遗嘱消息,具体描述见 3.1.2.5节。[MQTT-4.1.0-1]在整个会话期间,客户端和服务端都必须存储会话状态。[MQTT-4.1.0-2]会话必须至少持续和它的活跃网络连接同样长的时间。[MQTT-4.3.1-1]对于QoS 0的分发协议,发送者必须发送QoS等于0,DUP等于0的PUBLISH报文。[MQTT-4.4.0-1]客户端设置清理会话(CleanSession)标志为0重连时,客户端和服务端必须使用原始的报文标识符重发任何未确认的PUBLISH报文(如果QoS>0)和PUBREL报文。[MQTT-4.5.0-1]服务端接管入站应用消息的所有权时,它必须将消息添加到订阅匹配的客户端的会话状态中。匹配规则定义见 4.7节。[MQTT-4.5.0-2]客户端必须按照可用的服务质量(QoS)规则确认它收到的任何PUBLISH报文,不管它选择是否处理报文包含的应用消息。[MQTT-4.6.0-1]重发任何之前的PUBLISH报文时,必须按原始PUBLISH报文的发送顺序重发(适用于QoS 1和QoS 2消息)。[MQTT-4.6.0-2]必须按照对应的PUBLISH报文的顺序发送PUBACK报文(QoS 1消息)。[MQTT-4.6.0-3]必须按照对应的PUBLISH报文的顺序发送PUBREC报文(QoS 2消息)。[MQTT-4.6.0-4]必须按照对应的PUBREC报文的顺序发送PUBREL报文(QoS 2消息)。[MQTT-4.6.0-5]服务端必须默认认为每个主题都是有序的。它可以提供一个管理功能或其它机制,以允许将一个或多个主题当作是无序的。[MQTT-4.6.0-6]服务端处理发送给有序主题的消息时,必须按照上面的规则将消息分发给每个订阅者。此外,它必须按照从客户端收到的顺序发送PUBLISH报文给消费者(对相同的主题和QoS)。[MQTT-4.7.1-1]主题过滤器中可以使用通配符,但是主题名不能使用通配符。[MQTT-4.7.1-2]多层通配符必须位于它自己的层级或者跟在主题层级分隔符后面。不管哪种情况,它都必须是主题过滤器的最后一个字符。[MQTT-4.7.1-3]在主题过滤器的任意层级都可以使用单层通配符,包括第一个和最后一个层级。然而它必须占据过滤器的整个层级。[MQTT-4.7.2-1]服务端不能将 $ 字符开头的主题名匹配通配符 (#或+) 开头的主题过滤器。[MQTT-4.7.3-1]所有的主题名和主题过滤器必须至少包含一个字符。[MQTT-4.7.3-2]主题名和主题过滤器不能包含空字符 (Unicode U+0000) [Unicode] 。[MQTT-4.7.3-3]主题名和主题过滤器是UTF-8编码字符串,它们不能超过65535字节。[MQTT-4.7.3-4]匹配订阅时,服务端不能对主题名或主题过滤器执行任何规范化(normalization)处理,不能修改或替换任何未识别的字符。[MQTT-4.8.0-1]除非另有说明,如果服务端或客户端遇到了协议违规的行为,它必须关闭传输这个协议违规控制报文的网络连接。[MQTT-4.8.0-2]如果客户端或服务端处理入站控制报文时遇到了瞬时错误,它必须关闭传输那个控制报文的网络连接。[MQTT-6.0.0-1]MQTT控制报文必须使用WebSocket二进制数据帧发送。如果收到任何其它类型的数据帧,接收者必须关闭网络连接。[MQTT-6.0.0-2]单个WebSocket数据帧可以包含多个或者部分MQTT报文。接收者不能假设MQTT控制报文按WebSocket帧边界对齐。[MQTT-6.0.0-3]客户端必须将字符串 mqtt 包含在它提供的WebSocket子协议列表里。[MQTT-6.0.0-4]服务端选择和返回的WebSocket子协议名必须是 mqtt[MQTT-7.0.0-1]MQTT实现可以同时是MQTT客户端和MQTT服务端。接受入站连接和建立到其它服务端的出站连接的服务端必须同时符合MQTT客户端和MQTT服务端的要求。[MQTT-7.0.0-2]为了与任何其它的一致性实现交互操作,一致性实现不能要求使用在本规范之外定义的任何扩展。[MQTT-7.1.1-1]满足一致性要求的服务端必须支持使用一个或多个底层传输协议,只要它提供有序的、可靠的、双向字节流(从客户端到服务端和从服务端到客户端)[MQTT-7.1.2-1]满足一致性要求的客户端必须支持使用一个或多个底层传输协议,只要它提供有序的、可靠的、双向字节流(从客户端到服务端和从服务端到客户端)有想了解的可以了解一下,强制性规范声明是在官网处了解的,详细内容可以去官网查看
  • [技术干货] MQTT报文格式(第二篇)
    上一篇博客在这里:MQTT控制报文格式_IoT物联网_华为云论坛 (huaweicloud.com)4、剩余长度位置:从第2个字节开始。剩余长度(Remaining Length)表示当前报文剩余部分的字节数,包括可变报头和负载的数据。剩余长度不包括用于编码剩余长度字段本身的字节数。剩余长度字段使用一个变长度编码方案,对小于128的值它使用单字节编码。更大的值按下面的方式处理。低7位有效位用于编码数据,最高有效位用于指示是否有更多的字节。因此每个字节可以编码128个数值和一个延续位(continuation bit)。剩余长度字段最大4个字节。非规范评注例如,十进制数64会被编码为一个字节,数值是64,十六进制表示为0x40,。十进制数字321(=65+2*128)被编码为两个字节,最低有效位在前。第一个字节是 65+128=193。注意最高位为1表示后面至少还有一个字节。第二个字节是2。非规范评注这允许应用发送最大256MB(268,435,455)大小的控制报文。这个数值在报文中的表示是:0xFF,0xFF,0xFF,0x7F。剩余长度字段的大小 Size of Remaining Length field字节数最小值最大值10 (0x00)127 (0x7F)2128 (0x80, 0x01)16 383 (0xFF, 0x7F)316 384 (0x80, 0x80, 0x01)2 097 151 (0xFF, 0xFF, 0x7F)42 097 152 (0x80, 0x80, 0x80, 0x01)268 435 455 (0xFF, 0xFF, 0xFF, 0x7F)分别表示(每个字节的低7位用于编码数据,最高位是标志位):1个字节时,从0(0x00)到127(0x7f)2个字节时,从128(0x80,0x01)到16383(0Xff,0x7f)3个字节时,从16384(0x80,0x80,0x01)到2097151(0xFF,0xFF,0x7F)4个字节时,从2097152(0x80,0x80,0x80,0x01)到268435455(0xFF,0xFF,0xFF,0x7F)非规范评注 非负整数X使用变长编码方案的算法如下: ``` <span>do</span> encodedByte = X MOD <span>128</span> X = X DIV <span>128</span> <span>// if there are more data to encode, set the top bit of this byte if ( X > 0 ) encodedByte = encodedByte OR 128 endif 'output' encodedByte while ( X > 0 )</span> MOD是模运算,DIV是整数除法,OR是位操作或(C语言中分别是%,/,|) **非规范评注** 剩余长度字段的解码算法如下: ​ MOD是模运算,DIV是整数除法,OR是位操作或(C语言中分别是%,/,|) **非规范评注** 剩余长度字段的解码算法如下: multiplier = <span>1</span> value = <span>0</span> <span>do</span> encodedByte = <span>'next byte from stream'</span> value += (encodedByte AND <span>127</span>) multiplier <span>if</span> (multiplier > <span>128128128</span>) <span>throw</span> <span>Error</span>(Malformed Remaining Length) multiplier = <span>128</span> <span>while</span> ((encodedByte AND <span>128</span>) != <span>0</span>) ``` AND是位操作与(C语言中的&) 这个算法终止时,value包含的就是剩余长度的值。 ​二、可变报头某些MQTT控制报文包含一个可变报头部分。它在固定报头和负载之间。可变报头的内容根据报文类型的不同而不同。可变报头的报文标识符(Packet Identifier)字段存在于在多个类型的报文里。2.1、报文标识符Packet Identifier报文标识符字节 Packet Identifier bytesBit7 - 0byte 1报文标识符 MSBbyte 2报文标识符 LSB很多控制报文的可变报头部分包含一个两字节的报文标识符字段。这些报文是PUBLISH(QoS > 0时), PUBACK,PUBREC,PUBREL,PUBCOMP,SUBSCRIBE, SUBACK,UNSUBSCRIBE,UNSUBACK。SUBSCRIBE,UNSUBSCRIBE和PUBLISH(QoS大于0)控制报文必须包含一个非零的16位报文标识符(Packet Identifier)。客户端每次发送一个新的这些类型的报文时都必须分配一个当前未使用的报文标识符 。如果一个客户端要重发这个特殊的控制报文,在随后重发那个报文时,它必须使用相同的标识符。当客户端处理完这个报文对应的确认后,这个报文标识符就释放可重用。QoS 1的PUBLISH对应的是PUBACK,QoS 2的PUBLISH对应的是PUBCOMP,与SUBSCRIBE或UNSUBSCRIBE对应的分别是SUBACK或UNSUBACK。发送一个QoS 0的PUBLISH报文时,相同的条件也适用于服务端 。QoS等于0的PUBLISH报文不能包含报文标识符 。PUBACK, PUBREC, PUBREL报文必须包含与最初发送的PUBLISH报文相同的报文标识符 。类似地,SUBACK和UNSUBACK必须包含在对应的SUBSCRIBE和UNSUBSCRIBE报文中使用的报文标识符 。包含报文标识符的控制报文 Control Packets that contain a Packet Identifier控制报文报文标识符字段CONNECT不需要CONNACK不需要PUBLISH需要(如果QoS > 0)PUBACK需要PUBREC需要PUBREL需要PUBCOMP需要SUBSCRIBE需要SUBACK需要UNSUBSCRIBE需要UNSUBACK需要PINGREQ不需要PINGRESP不需要DISCONNECT不需要客户端和服务端彼此独立地分配报文标识符。因此,客户端服务端组合使用相同的报文标识符可以实现并发的消息交换。 
  • [技术干货] MQTT控制报文格式
    一、MQTT控制报文的结构MQTT协议通过交换预定义的MQTT控制报文来通信。MQTT控制报文由三部分组成:结构名解释Fixed header固定报头,报文的最开始部分所有控制报文都包含Variable header可变报头,固定报头的附加部分,仅部分控制报文包含Payload有效载荷,需要携带的信息内容,仅部分控制报文包含1、固定报头 Fixed header每个MQTT控制报文都包含一个固定报头。Bit76543210byte 1组合代表MQTT控制报文的类型指定控制报文类型的标志位,可以理解为一种属性参数byte 2...剩余长度2、MQTT控制报文的类型位置:第1个字节,二进制位7-4,表示为4位无符号值。如下:名字十进制数报文流动方向描述Reserved0禁止保留,不可以使用CONNECT1客户端到服务端客户端请求连接服务端CONNACK2服务端到客户端连接后回复报文确认PUBLISH3两个方向都允许发布消息(通过主题)PUBACK4两个方向都允许QoS 1消息发布收到确认PUBREC5两个方向都允许发布收到(保证交付第一步)PUBREL6两个方向都允许发布释放(保证交付第二步)PUBCOMP7两个方向都允许QoS 2消息发布完成(保证交互第三步)SUBSCRIBE8客户端到服务端客户端订阅请求,可一次订阅一个或多个SUBACK9服务端到客户端订阅请求报文确认UNSUBSCRIBE10客户端到服务端客户端取消订阅请求UNSUBACK11服务端到客户端取消订阅报文确认PINGREQ12客户端到服务端心跳请求(表示该数据包为通知服务端,客户端还在正常连接中)PINGRESP13服务端到客户端心跳响应(表示服务端已经成功收到了客户端的心跳请求)DISCONNECT14客户端到服务端客户端断开连接Reserved15禁止保留,不可以用3、标志固定报头第1个字节的剩余的4位 [3-0]包含每个MQTT控制报文类型特定的标志,控制报文固定报头标志Bit 3Bit 2Bit 1Bit 0CONNECT保留0000CONNACK保留0000PUBLISH在 MQTT 3.1.1中使用控制报文的重复分发标志PUBLISH报文的服务质量等级PUBLISH报文的服务质量等级PUBLISH报文的保留标志PUBACK保留0000PUBREC保留0000PUBREL保留0010PUBCOMP保留0000SUBSCRIBE保留0010SUBACK保留0000UNSUBSCRIBE保留0010UNSUBACK保留0000PINGREQ保留0000PINGRESP保留0000DISCONNECT保留0000今天闲来无事就先总结一些基础又容易忘的东西,所以就先从MQTT开始下手了,虽然知道还没整理完,但是写这个东西有点累了,歇会才能继续干,嘿嘿。
  • [问题求助] 能用华为云设备接入的MQTT协议做语音对讲功能吗
    用华为云-设备接入的MQTT协议,不知道能否做设备间的语音对讲功能?若可以,请讲讲思路吧。
  • [问题求助] ATK-HC05蓝牙模块与手机连接问题
    蓝牙模块第一次与手机配对时输入密码后配对成功 但是上电重启模块后,手机蓝牙设置中虽然显示之前配对过hc05,但模块本身并未进入配对状态。
  • [问题求助] mqtt.fx无法订阅mqtt主题
    我已经成功连接华为平台,并能向平台发送信息。现在我想在mqtt.fx订阅这个主题,但是这个订阅的按钮无法点击,所以华为的mqtt主题应该怎么订阅。
  • [问题求助] 使用Postman调测通过,使用Python却报IOTDA.000001
    我在使用上层应用控制下层ESP32,需要用到平台下发命令,我是用Postman调测通过,但是使用Python时却报了{"error_code":"IOTDA.000001","error_msg":"Internal server error."}以下是我的代码import requests url = "XXXX" payload = { "service_id" : "SmokeDetectorControl", "command_name" : "ON_OFF", "paras" : { "value" : "1" } } headers = { 'x-auth-token': 'XXXXXX' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text)与API explorer示例代码基本一致,希望哪位朋友能帮我看一下,不胜感激
  • [问题求助] 使用Mqtt协议发布订阅消息,在控制台能跟踪到数据,但是订阅代码或者MQTT.fx上没有数据打印
    测试实例:华为云IoTDA实例(标准版免费单元)根据官网自定义了Topic,并使用Mqtt.fx工具发送/订阅数据,在华为云控制太可以监控到数据,但是在Mqtt.fx工具不能正常订阅数据以下是测试相关图片:1. 使用mqtt.fx发送数据到指定topic2. 在华为云控制台可以监控到数据3. 在mqtt.fx工具中不能显示订阅的消息4. 使用官网给出的python-demo,也出现相同的情况,可以publish数据,在控制台可以看到数据,但是,subscribe不能正常打印数据,但是,代码中已经定义了on_message,貌似不生效
  • [技术干货] MQTT X Web:在线的 MQTT 5.0 客户端工具【转载】
    由 EMQ 开源的 MQTT X 是一款 MQTT 5.0 跨平台桌面客户端。MQTT X 为连接测试各类 MQTT 消息服务器而生,支持快速创建多个同时在线的 MQTT 客户端连接,采用一键式的连接方式和简洁的图形界面,帮助使用者便捷地测试 MQTT/TCP、MQTT/TLS、MQTT/WebSocket 的连接、发布、订阅功能,探索更多 MQTT 协议特性。在近期发布的 v1.8.0 中,除了通过新增的快速复制连接功能优化使用体验之外,还扩展了两个新的使用场景,即增加了 CLI(命令行) 和 Web 端(浏览器网页)这两种新的交互方式 。这使得 MQTT X 1.8.0 成为支持使用场景最完整的 MQTT 客户端工具。用户可以根据使用需求,自行选择下载桌面客户端、使用终端命令行或是在桌面浏览器上快速完成对 MQTT 的连接测试。MQTT X Web 介绍对于一些初次体验 MQTT 协议的新用户来说,快速理解并上手使用 MQTT 协议是首要需求。MQTT X Web 则为其提供了一种更为便捷的方式:无需繁杂的下载安装步骤,只需在浏览器内打开页面,即可快速连接和测试 MQTT 服务与应用,了解和探索 MQTT 协议。MQTT X Web 是一款在线 MQTT 5.0 客户端工具,即运行在浏览器上的 MQTT 5.0 WebSocket 客户端工具。其具有以下功能特性:支持通过普通或者加密的 WebSocket 端口连接至 MQTT 服务;连接的新建、编辑、删除以及缓存连接,方便下次访问使用;不同连接的订阅列表管理;消息发布、接收、以及接收到新消息时提示,同时也支持按照消息类型过滤消息列表。MQTT X Web 网站:cid:link_11MQTT X Web 在线使用地址:cid:link_5MQTT X Web GitHub 仓库:cid:link_2MQTT over WebSocket近年来随着 Web 前端的快速发展,浏览器新特性层出不穷,越来越多的应用可以在浏览器端通过浏览器渲染引擎实现,Web 应用的即时通信方式 WebSocket 也因此得到了广泛的应用。MQTT X Web 核心就是使用 WebSocket 连接到 MQTT 服务,因此从功能性来说,MQTT X Web 不仅使用方便,还能提供 MQTT over WebSocket 的连接测试功能。当您需要在 Web 应用场景中使用 MQTT 时,就可以通过 WebSocket 来连接和使用,使用 MQTT X Web 来调试您的 MQTT 服务与应用,加快您的应用生产并提高稳定性。基于现代浏览器MQTT X Web 基于现代浏览器技术开发,将应用部署到网页上。用户无需下载和安装 MQTT X 软件包,打开浏览器即可使用。同时还可将新建的连接和消息信息等持久化存储到浏览器内,方便下次访问使用。开放源码MQTT X Web 代码与 MQTT X 桌面应用和 MQTT X CLI 保持一致,基于 Apache License 2.0 协议开放源码,高级用户可以直接到代码仓库内修改和使用 MQTT X Web,并将其部署到任意您的使用环境中。使用 MQTT X Web 开发和调试 MQTT 服务与应用MQTT X Web 同样使用了图形化页面,采用聊天界面形式来帮助您快速测试 MQTT 服务,使用方式与 MQTT X 桌面应用基本一致。打开浏览器后输入 cid:link_4 就可以访问到 MQTT X Web。更多详细的使用介绍可以参考 MQTT X 的使用文档:cid:link_6。为测试 MQTT X Web 的使用,我们需要准备一个 MQTT 服务,本文将使用 EMQ 提供的 免费公共 MQTT 服务器,该服务基于 MQTT 物联网云平台 - EMQX Cloud 创建,服务器接入信息如下:Broker: broker.emqx.ioTCP Port: 1883WebSocket Port: 8083创建连接点击页面中的的 New Connection 按钮,在页面里输入连接信息,点击右上角即可快速创建并连接到 MQTT 服务。订阅管理创建并成功连接后,点击订阅列表中的 New Subscription 按钮弹出订阅列表框,在该页面可进行新建/取消订阅操作。消息发布/接收点击页面右侧底部的输入框,可弹出消息发布框,填写好 Topic 及 Payload 字段后点击右下角的发布图标可发布消息,发布成功后的消息将会显示在消息列表的右侧。订阅主题所收到的消息将会显示在消息列表的左侧,可点击右上角的消息类型切换按钮只显示已接收或是已发送的消息。最后,我们再通过使用 MQTT X 的桌面客户端来和 MQTT X Web 连接到同一个 MQTT 服务,以测试和验证 MQTT X Web 的功能。首先使用 MQTT X Web 发布一条消息,通过 MQTT X 桌面客户端来接收,再反向使用 MQTT X 桌面客户端发送一条消息到 MQTT X Web。此时,我们可以看到两边都收到了各自收发的消息。至此,我们就完成了使用 MQTT X Web 对 MQTT 消息发布订阅功能的测试和验证。在接下来的 1.8.1 版本中,我们还将继续优化页面样式,完善测试功能,支持更多的 MQTT 5.0 属性设置等。结语MQTT X Web 的发布,为物联网开发者进行 MQTT 连接测试提供了一种新的选择。而对命令行调用、桌面客户端下载和在线浏览器这几种交互形式的完整支持,使得 MQTT X 1.8.0 可帮助不同使用场景需求的用户完成对 MQTT 服务或应用的开发与调试,从而提高用户自身相关业务能力与稳定性。简单易用的测试客户端工具 MQTT X 结合高效可靠的物联网消息服务器 EMQX,将帮助物联网开发者构建具有竞争力的物联网平台与应用。转载自https://www.emqx.com/zh/blog/online-mqtt-client
  • [技术干货] MQTT 常用命令行客户端工具Mosquitto CLI【转载】
    Mosquitto 是一个开源(EPL/EDL 许可证)的消息代理,安装之后默认提供了 mosquitto_pub 和 mosquitto_sub 两个命令行 MQTT 客户端工具。Mosquitto CLI 有多个配置选项,支持 TLS 证书连接、通过代理服务器连接,支持 debug 模式,在 debug 模式下可以获取更详细的消息信息。特性轻量级命令行工具,支持 debug 模式支持加密及非加密连接至 MQTT 服务器便于在远程服务器测试快速开始订阅mosquitto_sub -t 'test/topic' -v发布mosquitto_pub -t 'test/topic' -m 'hello world'转载自https://www.jianshu.com/p/aa1996da3ee5
  • [技术干货] MQTT 常用命令行客户端工具NanoMQ CLI【转载】
    NanoMQ 是用于物联网边缘的超轻量级 MQTT 消息服务器,它同时也内置了一个强大的 MQTT 协议性能测试工具 bench 及 MQTT 测试客户端。特性支持性能测试支持 MQTT 5.0可运行在边缘端支持从文件读取数据作为 payload快速开始性能测试工具 bench# 启动 10 个连接,每秒向主题 t 发送 100 条 Qos0 消息,其中每个消息负载的大小为 16 字节nanomq_cli bench pub -t t -h broker.emqx.io -s 16 -q 0 -c 10 -I 10# 启动 500 个连接,每个连接使用 Qos0 订阅 t 主题nanomq_cli bench sub -t t -h broker.emqx.io -c 500# 启动 100 个连接nanomq_cli bench conn -h broker.emqx.io -c 100MQTT 测试客户端# 向主题 t 发送 100 条 Qos2 消息测试。nanomq_cli pub -t t -h broker.emqx.io -q 2 -L 100 -m test# 订阅主题 tnanomq_cli sub -t t -h broker.emqx.io -q 1转载自https://www.jianshu.com/p/aa1996da3ee5
总条数:174 到第
上滑加载中