「javamqtt机制」java mqtt服务器搭建

博主:adminadmin 2023-03-19 22:43:08 203

今天给各位分享javamqtt机制的知识,其中也会对java mqtt服务器搭建进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

MQTT系列-MQTT的QoS介绍

MQTT设计了一套保证消息稳定传输的机制,包括消息应答、存储和重传。

为了保证消息被正确的接收

在这套机制下,提供了三种不同层次QoS(Quality of Service):

QoS 是消息的发送方(Sender)和接受方(Receiver)之间达成的一个协议:

::: warning

QoS是Sender和Receiver之间的协议,而不是Publisher和Subscriber之间的协议。

换句话说,Publisher发布了一条QoS1的消息,只能保证Broker能至少收到一次这个消息;

而对于Subscriber能否至少收到一次这个消息,还要取决于Subscriber在Subscribe的时候和Broker协商的QoS等级。

:::

QoS0等级下,Sender和Receiver之间一次消息的传递流程如下:

Sender向Receiver发送一个包含消息数据的PUBLISH包,然后不管结果如何,丢掉已发送的PUBLISH包,一条消息的发送完成。

QoS1要保证消息至少到达一次,所以有一个应答的机制。Sender和Receiver的一次消息的传递流程如下:

1.Sender向Receiver发送一个带有数据的PUBLISH包,并在本地保存这个PUBLISH包;

2.Receiver收到PUBLISH包以后,向Sender发送一个PUBACK数据包,PUBACK数据包没有消息体(Payload),在可变头中有一个包标识(Packet Identifier),和它收到的PUBLISH包中的Packet Identifier一致。

3.Sender收到PUBACK之后,根据PUBACK包中的Packet Identifier找到本地保存的PUBLISH包,然后丢弃掉,一次消息的发送完成。

但是消息传递流程中可能会出现问题:

相比QoS0和QoS1,QoS2不仅要确保Receiver能收到Sender发送的消息,还需要确保消息不重复。它的重传和应答机制就要复杂一些,同时开销也是最大的。QoS2下,一次消息的传递流程如下所示:

1.Sender发送QoS为2的PUBLISH数据包,数据包 Packet Identifier 为 P,并在本地保存该PUBLISH包;

2.Receiver收到PUBLISH数据包后,在本地保存PUBLISH包的Packet Identifier P,并回复Sender一个PUBREC数据包,PUBREC数据包可变头中的Packet Identifier为P,没有消息体(Payload);

3.当Sender收到PUBREC,它就可以安全的丢弃掉初始Packet Identifier为P的PUBLISH数据包。同时保存该PUBREC数据包,并回复Receiver一个PUBREL数据包,PUBREL数据包可变头中的Packet Identifier为P,没有消息体;

4.当Receiver收到PUBREL数据包,它可以丢掉保存的PUBLISH包的Packet Identifier P,并回复Sender一个可变头中 Packet Identifier 为 P,没有消息体(Payload)的PUBCOMP数据包;

5.当Sender收到PUBCOMP包,那么认为传输已完成,则丢掉对应的PUBREC数据包;

上面是一次完整无误的传输过程,然而传输过程中可能会出现以下情况:

针对上述的问题,较为详细的处理方法如下:

Receiver收到PUBREL数据包后,正式将消息递交给上层应用层,投递之后销毁Packet Identifier P,并发送PUBCOMP数据包,销毁之前的持久化消息。

之后不管接收到多少个PUBREL数据包,因为没有Packet Identifier P,直接回复PUBCOMP数据包即可。

在 MQTT 协议中,从 Broker 到 Subscriber 这段消息传递的实际 QoS 等于:Publisher 发布消息时指定的 QoS 等级和 Subscriber 在订阅时与 Broker 协商的 QoS 等级,这两个 QoS 等级中的最小那一个。

Actual Subscribe QoS = MIN(Publish QoS, Subscribe QoS)

如果 Client 想接收离线消息,必须使用持久化的会话(Clean Session = 0)连接到 Broker,这样 Broker 才会存储 Client 在离线期间没有确认接收的 QoS 大于 等于1 的消息。

在以下情况下你可以选择 QoS0:

在以下情况下你应该选择 QoS1:

在以下情况下你应该选择 QoS2:

Java/Android:关于ActiveMQ与MQTT的关系是什么?

实在看不下去了,网上怎么竟是些胡说八道的呢。太坑人。MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议,activemq只是apache下一个队列项目,不仅仅支持MQTT协议,也支持其他比如AMQP等协议。MQTT是协议,协议只是定义好的规则,比如文档也是协议。activemq只是实现了MQTT协议的一个程序

【内部分享】MQTT协议解读及使用经验

时间:2018-07-26

Q: 什么是网络连接?

A: 网络连接是传输层定义的概念,在传输层以下只存在网络数据包的相互交换。

所谓连接,其实也不是在网络上有一条真实存在的数据通道。只要通信双方在一段时间内持续保持数据包交换,就可以视为双方建立的连接并没有断开。

连接的建立是依托于TCP协议的三次握手,一旦连接已经建立完毕,通信双方就可以复用这条虚拟通道进行数据交换。如果连接保持长时间工作一直没有被中断,那么这样的TCP连接就俗称为长连接。

Message Queue Telemetry Transport ,中文直译: 消息队列遥测传输协议 。

在MQTT协议被设计出来的年代,还没有物联网这么时髦的词汇,当年叫做 遥测设备 。

MQTT协议真正开始声名鹊起的原因,是其正好恰恰踩中移动互联网发展的节拍,为消息推送场景提供了一个既简便又具有良好扩展性的现成解决方案。

可以看出,MQTT对消息头的规定十分精简, 固定头部占用空间大小仅为1个字节 ,一个最小的报文占用的空间也 只有两个字节 (带一字节的长度标识位)。

这也是MQTT协议针对不稳定及带宽低下的网络环境做出的特定设计 - - - - 尽可能地节省一切不必要的网络开销 。

Q:为什么MQTT协议需要心跳报文(PINGREQ, PINGRESP)来维护连接状态,只监控该TCP的连接状态是否可以实现目的?

A: TCP数据传输默认的超时时间过长,不符合应用层上细粒度的要求。

TCP数据传输超时的情况可分成三种: 服务端断开 、 客户端断开 、 中间网络断开 。

在前两种场景下,若断开操作是一方主动发起的,即表示为TCP连接正常结束,双方走四次挥手流程;若程序异常结束,则会触发被动断开事件,通信另一方也能立刻感知到本次连接所打开的 Socket 出现中断异常。

唯独中间网络的状态是通信双方不能掌握的。 在Linux系统下 ,TCP的连接超时由内核参数来控制,如果通信中的一方没有得到及时回复,默认会主动再尝试 6次 。如果还没有得到及时回应,那么其才会认定本次数据超时。

连带首次发包与六次重试,Linux系统下这7次发包的超时时间分别为 2的0次方 至 2的6次方 ,即1秒、2秒、4秒、8秒、16秒、32秒、64秒,一共127秒。MQTT协议认为如此长的超时时间对应用层而言粒度太大,因此其在应用层上还单独设计属于自身的心跳响应控制。常见的MQTT连接超时多被设定为 60秒 。

扩展知识 - TCP的KeepAlive机制:

由通信中的 报文标识符 ( Packet Identifier )传达。

Q:仅Publish与Pubrec能保证消息只被投递一次吗?

A: 业务上可以实现,但MQTT协议并没有如此设计,原因如下:

每个消息都会拥有属于自己的报文标识符,但如果需要两次数据交换就实现消息仅只收到一次,就需要通信双方记录下每次使用的报文标识符,并且在处理每一条消息时都需要去重处理,以防消息被重复消费。

但MQTT协议最初被设计的工作对象是轻量级物联设备,为此在协议的设计中报文标识符被约定为 可重用 ,以减少对设备性能的消耗,换回的代价不得不使用四次网络数据交换,才能确保消息正好被消费一次。

Q:两个不同客户端在发布与订阅同一Topic下的消息时,都可以提出通信Qos要求,此时以哪项为基准?

A: 伪命题,故意在分享时埋下坑,等人来踩。

两个不同客户端的通信是需要 Broker 进行中转,而不是直连。因此,通信中存在两个不同的会话,双方的Qos要求仅仅作用于它们与 Broker 之间的会话,最终的Qos基准只会向最低要求方看齐。

例:遗嘱消息的正确使用方式可参考此篇文章:

虽然可以借助 Retain Message 实现绑定一条消息至某个Topic,以达到消息的暂时保留目的。

但首先 Retain Message 并不是为存储场景而设计的,再次MQTT协议并没有对消息的持久化作出规定,也就是说Broker重启后,现有保留消息也将丢失。

Q:两种特殊消息的使用场景?

A: 遗嘱消息,多用于客户端间获取互相之间异常断线的消息通知;

保留消息,可保存 最近一条 广播通知,多用于公告栏信息的发布。

Eclipse Mosquitto :MQTT协议的最小集实现

有 EMQ , HiveMQ , RabbitMQ MQTT Adapter 等。

Qos=2 消息保障的网络I/O次数过多,如果不是必需,尽少在程序里使用此类消息。

毕竟当初其设计的目的是为了减少设备的性能占用,但若应用场景并不是物联网,而是用于手机、电脑或浏览器端等现在已不缺性能的设备上,最好在报文体中,使用UUID生成全局唯一的消息ID,然后自行在业务解析中判断此报文是否被消费过。

或者,业务方在处理消息时保证其被消费的幂等性,也可消除重复消息对系统带来的影响。

正如MQTT协议并没有依赖TCP连接状态,自己在应用层协议上实现心跳报文来控制连接状态,业务方作为MQTT协议的使用者,也不要完全依赖协议的工作状态,而是依托MQTT协议建立属于业务本身的信息汇报机制,以加强系统的稳健性。

Retain Message 可视为客户端主动拉取的行为。如果业务系统采用 HTTP+MQTT 双协议描述业务过程,主动拉取的操作也可使用 HTTP 请求替代。

作为一个长连接型的应用,上线前需要根据业务量级,评估对操作系统 端口数 与 文件描述符 的占用要求,以防服务器资源被打满。

在服务端的配置文件和客户端的连接参数中,都拥有 max_inflight_messages 此项配置,来维护 Qos=1 or 2 消息是否被成功消费的状态。

MQTT 最初被设计为物联网级的通信协议,因此此参数的默认配额较小(大多数情况下被限制到10至20)。

但如果将MQTT协议应用至手机、PC或Web端的推送场景时,硬件性能已不在是瓶颈,在实际使用中推荐把此参数调大。

Mosquitto提供Bridge功能,需要我们自己配置。

Bridge 意为桥接,当我们把两台Broker桥接在一起时,只需要修改一台Broker的配置,填上另一台Broker的运行地址。前一台Broker将作为客户端发布与订阅后一台Broker的所有Topic,实现消息互通的目的。

桥接带来的问题有以下几点:

我的建议:

Websockets协议被设计的目的是为浏览器提供一个全双工的通信协议,方便实现消息推送功能。

在Websockets协议被设计出来前,受限于HTTP协议的一问一答模型,消息的推送只能靠轮询来实现,在资源消耗与时效性保障上,均难以达到令人满意的效果。

Websockets协议复用了HTTP协议的头部信息,告知浏览器接下来的操作将触发协议升级,然后通信双方继续复用HTTP的Header,但报文内容已转变为双方均接受的新协议的格式。

Websockets协议改进了网页浏览中的消息推送的方式,因此被广泛应用在聊天、支付通知等实时性要求比较高的场合下。

MQTT协议重点在于 消息队列的实现,其对消息投递的方式作出约定,并提供一些额外的通信保障 。

MQTT可采取原生的TCP实现,也有基于Websockets的实现版本。当然后者在网络字节的利用率上,不如前者那么精简。但浏览器端无法直接使用TCP协议,所以就只能基于Websockets协议开发。

不过基于Websockets的应用也有方便之处:一是证书不需要额外配置,直接与网站共用一套基础设施;二是可使用 Nginx 等工具管理流量,与普通HTTP流量可共用一套配置方法。

MQTT非常适合入门,原因如下:

实际的应用场景远比理想中的复杂,无法一招走遍天下,必须做好取舍。

MQTT协议在这方面做得很优秀,以后工作中可以作为参考,设计好自己负责的业务系统。

一文读懂物联网的灵魂MQTT

名词释义:

MQTT——Message Queuing Telemetry Transport消息队列遥测传输

PUB——Publish发布

QoS——Quality of Service服务质量

LWT——Last Will Testament最后遗嘱

MQTT简介

3.2 通配符

MQTT 中有两个可用的通配符,分别是+和#,+表示匹配单一层级中的任意主题,#表示匹配任意数量的层次。

3.3 服务质量(QoS)

MQTT 的设计初衷是为了在不可靠的网络中运作良好,为不同的场景提供了三个级别的服务质量,允许客户端指定自己想要的可靠性级别。

3.3.1 QoS Level 0:至多一次

这是最简单的级别,无需客户端确认,其可靠性与基础网络层 TCP/IP 一致。

3.3.2 QoS Level 1:至少一次,有可能重复

确保至少向客户端发送一次信息,不过也可发送多次;在接收数据包时,需要客户端返回确认消息(ACK 包)。这种方式常用于传递确保交付的信息,但开发人员必须确保其系统可以处理重复的数据包。

3.3.3 QoS Level 2:只有一次,确保消息只到达一次

这是最不常见的服务质量级别,确保消息发送且仅发送一次。这种方法需要交换4个数据包,同时也会降低消息代理的性能。由于相对比较复杂,在 MQTT 实现中通常会忽略这个级别,请确保在选择数据库或消息代理前检查这个问题。

3.4 “临终遗嘱”信息

MQTT提供了检测方式,利用KeepAlive机制在客户端异常断开时发现问题。因此当客户端电量耗尽、崩溃或者网络断开时,消息代理会采取相应措施。

客户端会向任意点的消息代理发送“临终遗嘱”(LWT)信息,当消息代理检测到客户端离线(连接并未关闭),就会发送保存在特定主题上的 LWT 信息,让其它客户端知道该节点已经意外离线。

3.5保留消息 Retained Messages

1个Topic只有唯一的retain消息,Broker会保存每个Topic的最后一条retain消息。

如何对java mqtt程序测试性能

Java编程下用JMeter Java Sampler进行多接口性能测试,使用方法如下:

/**

*JMeter Java Sampler介绍

*setupTest做些初始化的工作,每个线程只执行一次

*teardownTest做些清理工作,每个线程只执行一次

*runTest具体的测试执行工作,每个并发每次循环都将执行一次

**/

//继承AbstractJavaSamplerClient

public class hessianTest extends AbstractJavaSamplerClient{

//hessian调用地址

private static String url = "";

MyService collect = null;

HessianProxyFactory factory = new HessianProxyFactory();

public int id;

@Override

public void setupTest(JavaSamplerContext arg0) {

//获取jmeter传入参数

id=arg0.getIntParameter("id");

try {

collect = (MyService) factory.create(

MyService.class, url);

} catch (MalformedURLException e) {

e.printStackTrace();

}

}

@Override

public SampleResult runTest(JavaSamplerContext arg0) {

SampleResult sp = new SampleResult();

sp.sampleStart();

User rt = null;

try {

rt = collect.getUser(id);

} catch (Exception e) {

sp.sampleEnd();

sp.setSuccessful(false);

return sp;

}

sp.sampleEnd();

if(rt.getId()==id)

sp.setSuccessful(true);

else

sp.setSuccessful(false);

return sp;

}

@Override

public void teardownTest(JavaSamplerContext context) {

super.teardownTest(context);

}

}

3. MQTT简要介绍

——

[1.MQTT项目工程]()

[2.MQTT API说明文档]()

[3.MQTT协议中文版]()

MQTT是一个客户端服务端架构的发布/订阅模式的消息传输协议。它的设计思想是轻巧、开放、简单、规范,易于实现。这些特点使得它对很多场景来说都是很好的选择,特别是对于受限的环境如机器与机器的通信(M2M)以及物联网环境(IoT)。

MQTT协议通过交换预定义的MQTT控制报文来通信。

报文格式: 固定包头+可变包头+payload。

固定包头: 由两个字节组成

                byte1 高四位表示控制报文的类型,低四位表示控制报文类型的标志位。

                byte2表示剩余长度,包括可变报头和负载的数据。剩余长度不包括用于编码剩余长度字段本身的字节数。

可变包头:

                某些MQTT控制报文包含一个可变报头部分。它在固定报头和负载之间。可变报头的内容根据报文类型的不同而不同。可变报头的报文标(Packet Identifier)字段存在于在多个类型的报文里。

有效载荷:

                对于PUBLISH来说有效载荷就是应用消息。

——1. 网络建立连接后,客户端发送的第一个报文必须是CONNECT报文

——2. 客户端只能发送一次CONNECT 报文,发送两次会当作协议违规处理,并断开连接。

——3. 有效载荷包括:客户端唯一标识符,will主题,will消息,用户名和密码。

——4.可变包头:协议名(protocol name)+协议级别(protocol level)+连接标志(connect flags)+保持连接(keep alive)。

——5. 协议名: MQTT的UTF-8编码的字符串。(MSB+LSB +MQTT 六个字节)

——6. 协议级别:一个字节

——7. 连接标志:一个字节,包含一些用于指定MQTT连接行为的参数。同时还指出有效载荷中的字段是否存在。服务端必须验证CONNECT控制报文的保留标志位(第0位)是否为0,如果不为0必须断开客户端连接。

——8. 清理会话:byte8 的bit1位标志。

        这个二进制位指定了会话状态的处理方式。客户端和服务端可以保存会话状态,以支持跨网络连接的可靠消息传输。这个标志位用于控

       制会话状态的生存时间。

        标志设置为0:服务端必须基于当前会话(使用客户端标识符识别)的状态恢复与客户端的通信。

        标志设置为1:客户端和服务端必须丢弃之前的任何会话并开始一个新的会话。会话仅持续和网络连接同样长的时间。

——9. 遗嘱标志 WILL FLAG: byte8的bit2位标志。

        遗嘱标志(Will Flag)被设置为1,表示如果连接请求被接受了,遗嘱(Will Message)消息必须被存储在服务端并且与这个网络连接关联。之后网络连接关闭时,服务端必须发布这个遗嘱消息,除非服务端收到DISCONNECT报文时删除了这个遗嘱消息。

服务端发送CONNACK报文响应从客户端收到的CONNECT报文。服务端发送给客户端的第一个报文必须是CONNACK。

如果客户端在合理的时间内没有收到服务端的CONNACK报文,客户端应该关闭网络连接。合理 的时间取决于应用的类型和通信基础设施。

CONNACK报文没有有效载荷。

PUBLISH控制报文是指从客户端向服务端或者服务端向客户端传输一个应用消息。

固定包头:

注意byte1的bit3为重发标志DUP。

如果DUP标志被设置为0,表示这是客户端或服务端第一次请求发送这个PUBLISH报文。如果DUP标志被设置为1,表示这可能是一个早前报文请求的重发。

服务端发送PUBLISH报文给订阅者时,收到(入站)的PUBLISH报文的DUP标志的值不会被传播。发送(出站)的PUBLISH报文与收到(入站)的PUBLISH报文中的DUP标志是独立设置的,它的值必须单独的根据发送(出站)的PUBLISH报文是否是一个重发来确定。

可变包头:

主题名 :topic name

报文标识符 :packet identitfier。

有效载荷 :有效载荷包含将被发布的应用消息。数据的内容和格式是应用特定的。有效载荷的长度这样计算:用固定报头中的剩余长度字段的值减去可变报头的长度。包含零长度有效载荷的PUBLISH报文是合法的。

响应:PUBLISH报文的接收者必须按照根据PUBLISH报文中的QoS等级发送响应。

PUBACK报文是对QoS 1等级的PUBLISH报文的响应。

PUBACK报文没有有效载荷。

PUBREC报文是对QoS等级2的PUBLISH报文的响应。它是QoS 2等级协议交换的第二个报文。

PUBREC报文没有有效载荷。

PUBREL报文是对PUBREC报文的响应。它是QoS 2等级协议交换的第三个报文。

PUBREL报文没有有效载荷。

PUBCOMP报文是对PUBREL报文的响应。它是QoS 2等级协议交换的第四个也是最后一个报文。

PUBCOMP报文没有有效载荷。

客户端向服务端发送 SUBSCRIBE 报文用于创建一个或多个订阅。每个订阅注册客户端关心的一个或多个主题。为了将应用消息转发给与那些订阅匹配的主题,服务端发送PUBLISH报文给客户端。SUBSCRIBE报文也(为每个订阅)指定了最大的QoS等级,服务端根据这个发送应用消息给客户端。

有效载荷:

SUBSCRIBE报文的有效载荷包含了一个主题过滤器列表,它们表示客户端想要订阅的主题。SUBSCRIBE报文的有效载荷必须包含至少一对主题过滤器 和 QoS等级字段组合。没有有效载荷的SUBSCRIBE报文是违反协议的。

响应:

服务端收到客户端发送的一个SUBSCRIBE报文时,必须使用SUBACK报文响应,SUBACK报文必须和等待确认的SUBSCRIBE报文有相同的报文标识符。

服务端发送SUBACK报文给客户端,用于确认它已收到并且正在处理SUBSCRIBE报文。SUBACK报文包含一个返回码清单,它们指定了SUBSCRIBE请求的每个订阅被授予的最大QoS等级。

有效载荷:

有效载荷包含一个返回码清单。每个返回码对应等待确认的SUBSCRIBE报文中的一个主题过滤器。返回码的顺序必须和SUBSCRIBE报文中主题过滤器的顺序相同。

客户端发送UNSUBSCRIBE报文给服务端,用于取消订阅主题。

有效载荷 :

UNSUBSCRIBE报文的有效载荷包含客户端想要取消订阅的主题过滤器列表。

UNSUBSCRIBE报文中的主题过滤器必须是连续打包的、按照定义的UTF-8编码字符串 

UNSUBSCRIBE报文的有效载荷必须至少包含一个消息过滤器。没有有效载荷的UNSUBSCRIBE报文是违反协议的。

响应:

UNSUBSCRIBE报文提供的主题过滤器(无论是否包含通配符)必须与服务端持有的这个客 户端的当前主题过滤器集合逐个字符比较。如果有任何过滤器完全匹配,那么它(服务端)自己的订阅将被删除,否则不会有进一步的处理。

如果服务端删除了一个订阅:

——它必须停止分发任何新消息给这个客户端 []。

——它必须完成分发任何已经开始往客户端发送的QoS 1和QoS 2的消息 []。

——它可以继续发送任何现存的准备分发给客户端的缓存消息。

            服务端必须发送UNSUBACK报文响应客户端的UNSUBSCRIBE请求。UNSUBACK报文必须包含和UNSUBSCRIBE报文相同的报文标识符 。即使没有删除任何主题订阅,服务端也必须发送一个UNSUBACK响应 。

            如果服务端收到包含多个主题过滤器的UNSUBSCRIBE报文,它必须如同收到了一系列的多个UNSUBSCRIBE报文一样处理那个报文,除了将它们的响应合并到一个单独的UNSUBACK报文外。 

服务端发送UNSUBACK报文给客户端用于确认收到UNSUBSCRIBE报文。

UNSUBACK报文没有有效载荷。

客户端发送PINGREQ报文给服务端的。用于:

1. 在没有任何其它控制报文从客户端发给服务的时,告知服务端客户端还活着。

2. 请求服务端发送 响应确认它还活着。

3. 使用网络以确认网络连接没有断开。

保持连接(Keep Alive)处理中用到这个报文。

——PINGREQ报文没有可变报头。

——PINGREQ报文没有有效载荷。

响应:

服务端必须发送 PINGRESP报文响应客户端的PINGREQ报文。

服务端发送PINGRESP报文响应客户端的PINGREQ报文。表示服务端还活着。

保持连接(Keep Alive)处理中用到这个报文。

PINGRESP报文没有可变报头。

PINGRESP报文没有有效载荷。

DISCONNECT报文是客户端发给服务端的最后一个控制报文。表示客户端正常断开连接。

DISCONNECT报文没有可变报头。

DISCONNECT报文没有有效载荷。

响应:

客户端发送DISCONNECT报文之后:

—— 必须关闭网络连接 [MQTT-3.14.4-1]。

——不能通过那个网络连接再发送任何控制报文。

服务端在收到DISCONNECT报文时:

——必须丢弃任何与当前连接关联的未发布的遗嘱消息。

——应该关闭网络连接,如果客户端 还没有这么做。

为了提供服务质量保证,客户端和服务端有必要存储会话状态。在整个会话期间,客户端和服务端都必须存储会话状态 。会话必须至少持续和它的活跃网络连接同样长的时间。服务端的保留消息不是会话状态的组成部分。服务端应该保留那种消息直到客户端删除它。

MQTT协议要求基础传输层能够提供有序的、可靠的、双向传输(从客户端到服务端 和从服务端到客户端)的字节流。

无连接的网络传输协议如UDP是不支持的,因为他们可能会丢失数据包或对数据包重排序。

MQTT按照这里定义的服务质量 (QoS) 等级分发应用消息。分发协议是对称的,在下面的描述中,客户端和服务端既可以是发送者也可以是接收者。分发协议关注的是从单个发送者到单个接收者的应用消息。服务端分发应用消息给多个客户端时,每个客户端独立处理。分发给客户端的出站应用消息和入站应用消息的QoS等级可能是不同的。

qos0:最多分发一次

qos1:至少分发一次

qos2:仅分发一次

客户端设置清理会话(CleanSession)标志为0重连时,客户端和服务端必须使用原始的报文标识符重发任何未确认的PUBLISH报文(如果QoS0)和PUBREL报文 [MQTT-4.4.0-1]。这是唯一要求客户端或服务端重发消息的情况。

服务端接管入站应用消息的所有权时,它必须将消息添加到订阅匹配的客户端的会话状态。正常情况下,客户端收到发送给它的订阅的消息。客户端也可能收到不是与它的订阅精确匹配的消息。如果服务端自动给客户端分配了一个订阅,可能发生这种情况。正在处理UBSUBSCRIBE请求时也可能收到消息。客户端必须按照可用的服务质量(QoS)规则确认它收到的任何PUBLISH报文,不管它选择是否处理报文包含的应用消息 。

实现本章定义的协议流程时,客户端必须遵循下列规则:

重发任何之前的PUBLISH报文时,必须按原始PUBLISH报文的发送顺序重发(适用于QoS 1和QoS 2消息)[MQTT-4.6.0-1]。

——必须按照对应的PUBLISH报文的顺序发送PUBACK报文(QoS 1消息)。

——必须按照对应的PUBLISH报文的顺序发送PUBREC报文(QoS 2消息。

——必须按照对应的PUBREC报文的顺序发送PUBREL报文(QoS 2消息)。

服务端必须默认认为每个主题都是有序的。它可以提供一个管理功能或其它机制,以允许将一个或多个主题当作是无序的 。

服务端处理发送给有序主题的消息时,必须按照上面的规则将消息分发给每个订阅者。此外,它必须按照从客户端收到的顺序发送PUBLISH报文给消费者(对相同的主题和QoS)。

斜杠(‘/’ U+002F)用于分割主题的每个层级,为主题名提供一个分层结构.

数字标志(‘#’ U+0023)是用于匹配主题中任意层级的通配符。

加号 (‘+’ U+002B) 是只能用于单个主题层级匹配的通配符。

服务端不能将 $ 字符开头的主题名匹配通配符 (#或+) 开头的主题过滤器.

$SYS/ 被广泛用作包含服务器特定信息或控制接口的主题的前缀。

应用不能使用 $ 字符开头的主题。

订阅 “#” 的客户端不会收到任何发布到以 “$” 开头主题的消息。

订阅 “+/monitor/Clients” 的客户端不会收到任何发布到 “$SYS/monitor/Clients” 的消息。

订阅 “$SYS/#” 的客户端会收到发布到以 “$SYS/” 开头主题的消息。

订阅 “$SYS/monitor/+” 的客户端会收到发布到 “$SYS/monitor/Clients” 主题的消息。

如果客户端想同时接受以 “$SYS/” 开头主题的消息和不以 $ 开头主题的消息,它需要同

时订阅 “#” 和 ““$SYS/#”。

除非另有说明,如果服务端或客户端遇到了协议违规的行为,它必须关闭传输这个协议违规控制报文的网络连接.

MQTT方案通常部署在不安全的通信环境中。在这种情况下,协议实现通常需要提供这些机制:

——用户和设备身份认证

——服务端资源访问授权

——MQTT控制报文和内嵌应用数据的完整性校验

——MQTT控制报文和内嵌应用数据的隐私控制

作为传输层协议,MQTT仅关注消息传输,提供合适的安全功能是实现者的责任。使用TLS[RFC5246] 是比较普遍的选择。

广泛采用高级加密标准 [AES] 数据加密标准 [DES] 。

推荐使用为受限的低端设备特别优化过的轻量级加密国际标准 ISO 29192 [ISO29192] 。

如果MQTT在WebSocket [RFC6455] 连接上传输,必须满足下面的条件:

——MQTT控制报文必须使用WebSocket二进制数据帧发送。如果收到任何其它类型的数据帧,接收者必须关闭网络连接 。

——单个WebSocket数据帧可以包含多个或者部分MQTT报文。接收者不能假设MQTT控制报文按WebSocket帧边界对齐 。

——客户端必须将字符串 mqtt 包含在它提供的WebSocket子协议列表里 。

——服务端选择和返回的WebSocket子协议名必须是  。

——用于连接客户端和服务器的WebSocket URI对MQTT协议没有任何影响。

MQTT规范定义了MQTT客户端实现和MQTT服务端实现的一致性要求

MQTT实现可以同时是MQTT客户端和MQTT服务端。接受入站连接和建立到其它服务端的出站连接的服务端必须同时符合MQTT客户端和MQTT服务端的要求 。

为了与任何其它的一致性实现交互操作,一致性实现不能要求使用在本规范之外定义的任何扩展 。

附录:

控制报文类型

byte1:标志位flags:

关于javamqtt机制和java mqtt服务器搭建的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。