EMQ 学习---MQTT消息QoS

MQTT发布消息QoS保证不是端到端的,是客户端与服务器之间的。订阅者收到MQTT消息的QoS级别,最终取决于发布消息的QoS和主题订阅的QoS。

客户端连接:

客户端完成TCP三次握手之后,还需要发起CONNECT命令

注意:如果客户端三次握手之后,不发起MQTT的CONNECT命令,30s之后会被服务器断掉。

emqttd.config文件有定义这个时间间隔:

 %% Client
        {client, [
            %% Socket is connected, but no ‘CONNECT‘ packet received
            {idle_timeout, 30} %% seconds
        ]},

只有QoS==1,2时候,才有Store(Msg)之说;QoS==0时没有。

我们以第一种action为例(注意这里第一种action存储的是message,第二种action存储的是message ID):
1 若client没收到来自sever的pubcomp:那么client将重发pubrel,意思是sever将收到两次pubrel;但是sever并不会将消息发送两次,因为在第一次将消息发送给订阅者之后,server将删除这条消息的内容(delete message),而消息的内容是在publish中传输的,而不是在pubrel中传输的;
2 若client没收到来自server的pubrec,那么client将重发publish,意思是sever将收到两次publish,但是这里sever只是存储了信息,而且后面在pubrec中会有消息的ID,而client可以根据两次ID是否相同来判断server收到了几次同样的消息。
综上所述,这就保证了server不会将消息重发。

对于QoS2,增加了一个PUBREL及PUBCOM的过程,这样可以保证server端只publish一条message给他的subscriber。但是QoS1是只要sever接收到message就会publish给他的subscriber,网络不好的时候sender是会重复发送相同的message的,server也就会重复publish相同的message给他的。

QoS2的server端处理逻辑有点特别:

如果sender没收到server的PUBRECV, sender 是会重发,但是对于头上一条message,server有两种处理方式:1, message存在本地,先不publish给subscriber;2,存下message ID,把message publish 给他的subscriber。

对于第一种处理方式,如果sender继续重发,且被收到(ID相同),那在server端只算一条message,继续等sender发PUBREL,这样server就保证只publish了一条message,而不是多条。

对于第二种处理方式,如果sender继续重发,且被收到,sever会检查它的message ID,如果重发过来的message ID是之前存过的,server就不会publish给他的subscriber,因为之前已经publish了。直接删除。

总之,QoS==1,2时候,有Store(Msg)和唯一的MessageID来保证消息不会重复接收和发送!

原文地址:https://www.cnblogs.com/saryli/p/9782421.html

时间: 2024-10-21 15:34:19

EMQ 学习---MQTT消息QoS的相关文章

Android Mqtt 消息推送使用

初始化SDK: /** * 初始化SDK * * @param context context */ public void initSDK(Context context) { String clientId = String.valueOf(System.currentTimeMillis()+userId); mqttAndroidClient = new MqttAndroidClient(mContext, serverUri, clientId); subscriptionTopic

使用EMQ搭建MQTT服务器

前言寒假的时候开始搭建mqtt服务器,一开始使用的是RabbitMQ,基于Erlang语言.但是RabbitMQ的本职工作是AMQP,MQTT只是他的一个插件功能,似乎有些大材小用,很多MQTT的功能也没有集成.这次我打算使用EMQ来重新部署我的MQTT服务器.EMQ也是基于 Erlang/OTP 语言平台开发.他是支持大规模连接和分布式集群,发布订阅模式的开源 MQTT 消息服务器.支持的输入协议不仅仅是MQTT,还包括WebSocket,以及物联网同样著名的与MQTT基于TCP传输协议不同的

[3] MQTT,mosquitto,Eclipse Paho---如何使用 Eclipse Paho MQTT工具来发送订阅MQTT消息?

在上两节,笔者主要介绍了 MQTT,mosquitto,Eclipse Paho的基本概念已经如何安装mosquitto. 在这个章节我们就来看看如何用 Eclipse Paho MQTT工具来发送接收MQTT消息.Eclipse Paho MQTT工具是一个基于Java的Eclipse桌面客户端程序,其底层的和MQTT服务器进行的交互的java类库就是Eclipse Paho java库.假设我们在本机(127.0.0.1)已经启动了一个mosquitto MQTT服务器,其端口为1883.如

java基础学习之 消息对话款

1 package Dome; 2 import java.awt.event.*; 3 import java.awt.*; 4 import javax.swing.*; 5 6 public class WindowMess extends JFrame implements ActionListener 7 { 8 JTextField inputEnglish ; 9 JTextArea show ; 10 String regex = "[a-zZ-Z]+"; 11 Win

EMQ 学习---订阅$SYS主题,捕获客户端上下线消息

acl.config文件定义了可订阅$SYS主题的权限. {allow, {user, "dashboard"}, subscribe, ["$SYS/#"]}. {allow, {ipaddr, "127.0.0.1"}, pubsub, ["$SYS/#", "#"]}. %%%{deny, all, subscribe, ["$SYS/#", {eq, "#"}

MQTT 消息 发布 订阅

当连接向一个mqtt服务器时,clientId必须是唯一的.设置一样,导致client.setCallback总是走到 connectionLost回调.报connection reset.调查一天才发现是clientid重复导致. client = new MqttAsyncClient(serverURIString, "client-id"); clientId是用来保存会话信息. MqttConnectOptions options = new MqttConnectOptio

objc_msgSend消息传递学习笔记 – 消息转发

该文是 objc_msgSend消息传递学习笔记 – 对象方法消息传递流程 的基础上继续探究源码,请先阅读上文. 消息转发机制(message forwarding) Objective-C 在调用对象方法的时候,是通过消息传递机制来查询且执行方法.如果想令该类能够理解并执行方法,必须以程序代码实现出对应方法.但是,在编译期间向类发送了无法解读的消息并不会报错,因为在 runtime 时期可以继续向类添加方法,所以编译器在编译时还无法确认类中是否已经实现了消息方法. 当对象接受到无法解读的消息后

转: RabbitMQ实现中AMQP与MQTT消息收发异同

转自:http://www.cnblogs.com/lucifer1997/p/9438186.html 实现了AMQP与MQTT(至多一次)后,用多个队列以topic exchange的方式用相同交换机监听同一个主题(topic),发现情况存在不同,觉得有点意思,所以记录了下来. 用2个MQTT(分别记作A.B).2个AMQP(分别记作C.D)同时监听一个topic, 然后向这个topic先以MQTT的方式发送4条消息(分别记作1.2.3.4), 再以AMQP方式发送4条消息(分别记作5.6.

Windows安装EMQ服务器(mqtt)

先去EMQ官网下载安装包 https://www.emqx.io/downloads#broker 注意:此处一定不能下错成企业版的,不然EMQ会由于缺少企业license无法启动服务 解压到任意路径 注意:路径不能包含中文或者空格,不然可能会出错 然后切换到emqx/bin目录下,shift+右键,打开powershell 输入命令 ./start  启动服务   此外,也可使用./console 启动服务 然后等待一段时间后 ./emqx_ctl status  可查询到服务器的状态 启动成