mqtt 订阅
MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。它工作在 TCP/IP协议族上,是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议,为此,它需要一个消息中间件 。MQTT是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。其在,通过卫星链路通信传感器、偶尔拨号的医疗设备、智能家居、及一些小型化设备中已广泛使用。 展开全文
MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。它工作在 TCP/IP协议族上,是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议,为此,它需要一个消息中间件 。MQTT是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。其在,通过卫星链路通信传感器、偶尔拨号的医疗设备、智能家居、及一些小型化设备中已广泛使用。
信息
性    质
即时通讯协议
外文名
MQTT(Message Queuing Telemetry Transport)
开发商
IBM
中文名
消息队列遥测传输
支持平台
所有
MQTT简介
MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。它工作在TCP/IP协议族上,是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议,为此,它需要一个消息中间件。IBM公司的安迪·斯坦福-克拉克及Cirrus Link公司的阿兰·尼普于1999年撰写了该协议的第一个版本。该协议的可用性取决于该协议的使用环境。IBM公司在2013年就向结构化资讯标准促进组织提交了 MQTT 3.1 版规范,并附有相关章程,以确保只能对规范进行少量更改。MQTT-SN是针对非 TCP/IP 网络上的嵌入式设备主要协议的变种,与此类似的还有ZigBee协议。纵观行业的发展历程,“MQTT”中的“MQ” 是来自于IBM的MQ系列消息队列产品线。然而通常队列本身不需要作为标准功能来支持。可选协议包含了高级消息队列协议,面向文本的消息传递协议,互联网工程任务组约束应用协议,可扩展消息与存在协议,数据分发服务,OPC UA以及web 应用程序消息传递协议。 [1] 
收起全文
精华内容
下载资源
问答
  • MQTT

    万次阅读 多人点赞 2018-09-16 05:24:46
    MQTT-Learning-Note 简介:MQTT由IBM公司开发,是一个即时通讯协议,也是一个物联网传输协议,主要用于轻量级的订阅/发布式的消息传输。其设计目的主要是为低带宽和不稳定网络环境下的物联网设备提供服务。 MQTT...

    MQTT

    简介:MQTT由IBM公司开发,是一个即时通讯协议,也是一个物联网传输协议,主要用于轻量级的订阅/发布式的消息传输。其设计目的主要是为低带宽和不稳定网络环境下的物联网设备提供服务。

    MQTT中的概念

    • 订阅(Subscribtion):
      订阅包含主题筛选器(Topic Filter)和最大服务质量(QoS)。订阅会与一个会话(Session)关联。一个会话可以包含多个订阅。每一个会话中的每个订阅都有一个不同的主题筛选器。
    • 会话(Session):
      每个客户端与服务器建立连接后就是一个会话,客户端和服务器之间有状态交互。会话存在于一个网络之间,也可能在客户端和服务器之间跨越多个连续的网络连接。
    • 主题名(Topic Name):
      连接到一个应用程序消息的标签,该标签与服务器的订阅相匹配。服务器会将消息发送给订阅所匹配标签的每个客户端。
      需要注意的是,MQTT中消息主题按照层级命名,使用 ‘/’ 进行分割
      此外,主题中可以使用通配符进行多个主题或多层级的订阅,有两种常见的通配符:
      1. 单层通配符 +:单层通配符只能匹配一层的主题,例如:China/Beijing/+,可以匹配的只有Beijing这个主题下面一层的主题,例如Xicheng, DongCheng, Xuanwu等等。
      2. 多层通配符 #:顾名思义,多层通配符就是可以匹配多个层级的主题,例如:China/#,可以匹配到的主题可能有:China/Beijing/Dongcheng, China/Shanghai/PuDong,等等。
    • 主题筛选器(Topic Filter):
      一个对主题名通配符筛选器,在订阅表达式中使用,表示订阅所匹配到的多个主题。
    • 负载(Payload):
      消息订阅者所具体接收的内容。

    MQTT中的角色

    MQTT

    • Publisher和Subscriber为客户端,Broker为服务器端,消息主题为消息类型,Broker根据Topic过滤消息,并将消息向客户端推送。
    • MQTT中用QoS表示服务质量,MQTT协议中有三种服务质量(QoS):
      1. QoS =0,至多一次,可能会出现丢包的情况,使用在对实时性要求不高的情况,例如,将此服务质量与通信环境传感器数据一起使用。 对于是否丢失个别读取或是否稍后立即发布新的读取并不重要。
      2. QoS =1,至少一次,保证包会到达目的地,但是可能出现重包。
      3. QoS =2, 刚好一次,保证包会到达目的地,且不会出现重包的现象。

    客户端

    • Publisher和Subscriber都属于客户端。
    • 发布应用消息给其它相关的客户端。
    • 订阅以请求接受相关的应用消息。
    • 取消订阅以移除接受应用消息的请求。
    • 从服务端断开连接。

    服务器端

    • 服务器端即所谓的MQTT Broker服务器。
    • 接受来自客户端的网络连接。
    • 接受客户端发布的应用消息。
    • 处理客户端的订阅和取消订阅请求。
    • 转发应用消息给符合条件的已订阅客户端。
    • MQTT提供的公共服务器端(Broker)有:
      • test.mosquitto.org
      • broker.hivemq.com
      • iot.eclipse.org

    配置私有的MQTT服务器

    通常情况,出于安全考虑,一般使用私有的MQTT服务器端,MQTT的本地服务由Mosquitto支持。设置MQTT私有服务器端的方法如下(环境为Ubuntu16.04):

    # Install Mosquitto and Mosquitto-clients(optional)
    sudo apt-get install mosquitto
    
    # 默认情况下,ubuntu会自动启动Mosquitto服务,所以无需显式启动服务,此时可以查看mosquitto状态:
    sudo systemctl satus mosquitto

    mqtt test

    如果你只是想运行一个本地的MQTT服务,现在已经OK了。在mosquitto服务启动之后,你可以使用服务器的域名或者IP地址访问,MQTT服务器默认端口为1883。问题很明显,虽然我们设置了本地的私有MQTT服务器端,但是任何人都可以通过IP访问这台服务器,所以我们需要为mosquitto设置用户名和密码,只有拥有用户名和密码的客户端才可连接到服务器。

    Mosquitto客户端提供了为mosquitto设置密码的命令 mosquitto_passwd,这个命令其实就是将我们设置的用户名和密码copy进/etc/mosquitto/passwd这个文件:

    sudo mosquitto_passwd -c /etc/mosquitto/passwd <username>
    # 执行上面命令的时候会提示输入两次密码

    在生成了密码文件之后,我们需要告诉mosquitto服务,以后如果有客户端想创建连接请验证用户名和密码,具体操作如下:

    sudo bash -c 'sudo echo -e "allow_anonymous false\npassword_file /etc/mosquitto/passwd" > /etc/mosquitto/conf.d/default.conf'

    上面的命令创建default.conf并输入引号里面的命令,可以看到我们禁止了anonymous连接,并且指定了密码所在的文件。

    然后,重启mosquitto服务,让设置生效

    sudo systemctl restart mosquitto

    重新测试一下
    MQTT with username and password

    从上面的测试结果看出,现在我们的mosquitto服务器已经有了username和password的feature了。

    MQTT Python API(paho-mqtt)

    pip install paho-mqtt

    注: paho-mqtt这个库提供的函数主要是客户端的函数
    另外,在paho-mqtt库中,有一种重要的函数–回调函数。简单说一下回调函数,通常情况下,我们写应用程序代码时经常引入一些API,我们主动调用这些API里的函数,称为直调。反过来,如果让API调用我们定义好的函数,这就称为回调。在phao-client这个库中,on_connect, on_message, on_subscribe, on_publish等等这些均为回调函数, 这些回调函数由中间函数调用。简单看一下paho-client中的callback 是如何实现的(以subscribe为例):

    # 假设我们自定义的on_subscribe回调函数如下
    # 先不要管为什么要在函数中指定这些参数,后面会用到
    def on_subscribe(client, userdata, mid, granted_qos):
        print('Subscribed message: ', str(mid))
    
    # 然后我们使用如下语句设置回调
    client.on_subscribe = on_subscribe
    
    # 下面解释上面这行代码,查看paho-mqtt源码
    @property
    def on_subscribe(self):
        """If implemented, called when the broker responds to a subscribe
        request."""
        return self._on_subscribe
    
    @on_subscribe.setter
    def on_subscribe(self, func):
        """ Define the suscribe callback implementation.
    
        Expected signature is:
            subscribe_callback(client, userdata, mid, granted_qos)
    
        client:         the client instance for this callback
        userdata:       the private user data as set in Client() or userdata_set()
        mid:            matches the mid variable returned from the corresponding
                        subscribe() call.
        granted_qos:    list of integers that give the QoS level the broker has
                        granted for each of the different subscription requests.
        """
        with self._callback_mutex:
            self._on_subscribe = func

    从上面的代码可以看出, subscribe为Client类的一个property,我们使用的是subscribe属性的setter方法,设置类成员变量_on_subscribe的值。
    接下来,我们发出subscribe请求,下面paho-client处理subscribe请求的函数,函数的前半部分基本是对客户端传入参数topic的检查,忽略。从最后三行代码可以看出,客户端发送了topic_qos_list这条消息给了MQTT服务器端。

        def subscribe(self, topic, qos=0):
            topic_qos_list = None
    
            if isinstance(topic, tuple):
                topic, qos = topic
    
            if isinstance(topic, basestring):
                ...
            elif isinstance(topic, list):
                ...
    
            if topic_qos_list is None:
                raise ValueError("No topic specified, or incorrect topic type.")
    
            if any(self._filter_wildcard_len_check(topic) != MQTT_ERR_SUCCESS for topic, _ in topic_qos_list):
                raise ValueError('Invalid subscription filter.')
    
            if self._sock is None:
                return (MQTT_ERR_NO_CONN, None)
    
            return self._send_subscribe(False, topic_qos_list)

    在paho-mqtt中有一个函数_handle_suback来处理服务器返回给客户端subscribe请求的响应消息。具体消息接收的过程有好几个步骤,大体经过的函数有:loop –> loop_read –> _packet_read –> _packet_handle –> _handle_suback

    def _handle_suback(self):
         self._easy_log(MQTT_LOG_DEBUG, "Received SUBACK")
         pack_format = "!H" + str(len(self._in_packet['packet']) - 2) + 's'
         (mid, packet) = struct.unpack(pack_format, self._in_packet['packet'])
         pack_format = "!" + "B" * len(packet)
         granted_qos = struct.unpack(pack_format, packet)
    
         with self._callback_mutex:
             if self.on_subscribe:
                 with self._in_callback:  # Don't call loop_write after _send_publish()
                     self.on_subscribe(self, self._userdata, mid, granted_qos)
    
         return MQTT_ERR_SUCCESS

    好了,终于看到了在哪里调用了回调函数,现在明白了为什么要在创建on_subscribe的时候指定那些参数了吧。因为这些参数可能对回调函数本身没什么用,BUT,中间函数(也就是这里的_handle_suback)认为它们有用,并且在调用回调函数的时候传入了这些参数,所以我们定义的时候需要有这些参数。

    下面简单介绍paho-client的一些基本操作,只是简单列举一些函数,具体更多的可以查看官方Documentation

    # import mqtt客户端
    import paho.mqtt.client as mqtt
    
    # 创建客户端, client_id为必须参数,其余为可选参数
    client = mqtt.Client(client_id=””, clean_session=True, userdata=None, protocol=MQTTv311, transport=”tcp”)
    
    
    '''
    # 当客户端与服务器端连接成功后,服务器端会给客户端返回一个Ack消息,这个Ack会调用回调方法on_connect()来显示连接状态,用户可以自定义回调方法的内容
    params:
        rc: return code,表示服务器端返回的连接状态, 可能的值有:
            0: 连接成功
            1: 连接拒绝 --– 协议版本错误
            2. 连接拒绝 --- 客户端身份验证错误
            3. 连接拒绝 --- 服务器不存在
            4. 连接拒绝 --- 用户名/密码错误
            5. 连接拒绝 --- 未授权错误
            6-255. 连接拒绝 --- 当前不可用
    '''
    def on_connect(client, userdata, flags, rc):
        if rc==0:
            client.connected_flag = True
            print("connected OK Returned code=",rc)
        else:
            client.connected_flag = False
            print("Bad connection Returned code=",rc)
    
    # 设定自定义的on_connect回调函数
    client.on_connect = on_connect
    
    '''
    on_message()回调函数
    当订阅者收到Broker发布的消息之后,on_message()被调用
    params:
        message:
            :type MQTTMessage
            :attrs topic, payload, qos, retain
    '''
    def on_message(client, userdata, message):
        print("message received " ,str(message.payload.decode("utf-8")))
        print("message topic=",message.topic)
        print("message qos=",message.qos)
        print("message retain flag=",message.retain)
    
    client.on_message = on_message
    
    '''
    连接服务器端, host为broker的IP或者domain name
    params:
        host: 服务器端的IP地址或者Domain name
        keepalive: 客户端和服务器端交互的最长时间,当客户端和Broker之间没有交互的时候,客户端ping服务器端的频率,单位为秒
        bind_address: 在多网卡情况下,将客户端和某一局部网卡的IP地址绑定
    '''
    cient.connect(host, port=1883, keepalive=60, bind_address="")
    
    '''
    Loop Start
    loop_start()函数调用一次loop()函数
    loop()函数的作用为:读取、写入接收缓存区的或者发送缓冲区中的数据,并调用对应的回调函数。此外,loop函数还可以在连接断开的时候,重新建立与服务器端的连接.
    '''
    client.loop_start()
    
    # 此外,可以通过connect_flag来标记连接状态,主要用于等待连接成功
    while client.connected_flag is False:
        time.sleep()
    
    '''
    Publish Message
    只有topic和payload为必须参数,其余可选
    当客户端调用publish()方法时,会返回MQTTMessageInfo对象,该对象包含的属性和方法有:
        attr:
            rc(return code):
                MQTT_ERR_SUCCESS, MQTT_ERR_NO_CONN, MQTT_ERR_QUEUE_SIZE
            mid(message id)
            is_published
        function:
            wait_for_publish()
    当消息被发送给Broker之后,on_publish()回调方法会被调用
    '''
    client.publish(topic='$topic', payload='$payload', qos=0, retain=False)
    
    '''
    Subscribe Message
    此函数的参数有三种类型:
    1. Simple string and integer
        example: subscribe('my/topic', 0)
    2. String and integer tuple
        example: subscribe(('my/topic', 0))
    3. List of string and integer tuples
        exmaple: subscribe([('my/topic1', 0), ('my/topic', 2)])
    
    return: (result, mid)
        :type tuple
    
    当Broker收到订阅者的订阅请求之后,on_subscribe()回调函数会被调用
    '''
    client.subscribe(topic, qos=0)
    
    # 结束loop
    client.loop_stop()
    展开全文
  • MQTT--入门

    万次阅读 多人点赞 2017-10-24 00:27:13
    一、简述 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的“轻量级”通讯协议,该协议构建于TCP/IP协议上,由IBM在1999年发布。MQTT最大优点...

    无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家。教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家。点这里可以跳转到教程。


    一、简述

     MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的“轻量级”通讯协议,该协议构建于TCP/IP协议上,由IBM在1999年发布。MQTT最大优点在于,可以以极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。作为一种低开销、低带宽占用的即时通讯协议,使其在物联网、小型设备、移动应用等方面有较广泛的应用。

     MQTT是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。其在,通过卫星链路通信传感器、偶尔拨号的医疗设备、智能家居、及一些小型化设备中已广泛使用。

    在这里插入图片描述

    二、设计规范

    由于物联网的环境是非常特别的,所以MQTT遵循以下设计原则:

    (1)精简,不添加可有可无的功能;

    (2)发布/订阅(Pub/Sub)模式,方便消息在传感器之间传递;

    (3)允许用户动态创建主题,零运维成本;

    (4)把传输量降到最低以提高传输效率;

    (5)把低带宽、高延迟、不稳定的网络等因素考虑在内;

    (6)支持连续的会话控制;

    (7)理解客户端计算能力可能很低;

    (8)提供服务质量管理;

    (9)假设数据不可知,不强求传输数据的类型与格式,保持灵活性。

    三、主要特性

     MQTT协议工作在低带宽、不可靠的网络的远程传感器和控制设备通讯而设计的协议,它具有以下主要的几项特性:

    (1)使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合。

     这一点很类似于XMPP,但是MQTT的信息冗余远小于XMPP,,因为XMPP使用XML格式文本来传递数据。

    (2)对负载内容屏蔽的消息传输。

    (3)使用TCP/IP提供网络连接。

     主流的MQTT是基于TCP连接进行数据推送的,但是同样有基于UDP的版本,叫做MQTT-SN。这两种版本由于基于不同的连接方式,优缺点自然也就各有不同了。

    (4)有三种消息发布服务质量:

     “至多一次”,消息发布完全依赖底层TCP/IP网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。这一种方式主要普通APP的推送,倘若你的智能设备在消息推送时未联网,推送过去没收到,再次联网也就收不到了。

     “至少一次”,确保消息到达,但消息重复可能会发生。

     “只有一次”,确保消息到达一次。在一些要求比较严格的计费系统中,可以使用此级别。在计费系统中,消息重复或丢失会导致不正确的结果。这种最高质量的消息发布服务还可以用于即时通讯类的APP的推送,确保用户收到且只会收到一次。

    (5)小型传输,开销很小(固定长度的头部是2字节),协议交换最小化,以降低网络流量。

     这就是为什么在介绍里说它非常适合“在物联网领域,传感器与服务器的通信,信息的收集”,要知道嵌入式设备的运算能力和带宽都相对薄弱,使用这种协议来传递消息再适合不过了。

    (6)使用Last Will和Testament特性通知有关各方客户端异常中断的机制。

    Last Will:即遗言机制,用于通知同一主题下的其他设备发送遗言的设备已经断开了连接。

    Testament:遗嘱机制,功能类似于Last Will。

    四、MQTT协议原理

    4.1 MQTT协议实现方式

     实现MQTT协议需要客户端和服务器端通讯完成,在通讯过程中,MQTT协议中有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。

    MQTT传输的消息分为:主题(Topic)和负载(payload)两部分:

    (1)Topic,可以理解为消息的类型,订阅者订阅(Subscribe)后,就会收到该主题的消息内容(payload);

    (2)payload,可以理解为消息的内容,是指订阅者具体要使用的内容。

    4.2 网络传输与应用消息

     MQTT会构建底层网络传输:它将建立客户端到服务器的连接,提供两者之间的一个有序的、无损的、基于字节流的双向传输。

    当应用数据通过MQTT网络发送时,MQTT会把与之相关的服务质量(QoS)和主题名(Topic)相关连。

    4.3MQTT客户端

     一个使用MQTT协议的应用程序或者设备,它总是建立到服务器的网络连接。客户端可以:

    (1)发布其他客户端可能会订阅的信息;

    (2)订阅其它客户端发布的消息;

    (3)退订或删除应用程序的消息;

    (4)断开与服务器连接。

    4.4 MQTT服务器

     MQTT服务器以称为“消息代理”(Broker),可以是一个应用程序或一台设备。它是位于消息发布者和订阅者之间,它可以:

    (1)接受来自客户的网络连接;

    (2)接受客户发布的应用信息;

    (3)处理来自客户端的订阅和退订请求;

    (4)向订阅的客户转发应用程序消息。

    4.5 MQTT协议中的订阅、主题、会话

    一、订阅(Subscription)

     订阅包含主题筛选器(Topic Filter)和最大服务质量(QoS)。订阅会与一个会话(Session)关联。一个会话可以包含多个订阅。每一个会话中的每个订阅都有一个不同的主题筛选器。

    二、会话(Session)

     每个客户端与服务器建立连接后就是一个会话,客户端和服务器之间有状态交互。会话存在于一个网络之间,也可能在客户端和服务器之间跨越多个连续的网络连接。

    三、主题名(Topic Name)

     连接到一个应用程序消息的标签,该标签与服务器的订阅相匹配。服务器会将消息发送给订阅所匹配标签的每个客户端。

    四、主题筛选器(Topic Filter)

     一个对主题名通配符筛选器,在订阅表达式中使用,表示订阅所匹配到的多个主题。

    五、负载(Payload)

     消息订阅者所具体接收的内容。

    4.6 MQTT协议中的方法

     MQTT协议中定义了一些方法(也被称为动作),来于表示对确定资源所进行操作。这个资源可以代表预先存在的数据或动态生成数据,这取决于服务器的实现。通常来说,资源指服务器上的文件或输出。主要方法有:

    (1)Connect。等待与服务器建立连接。

    (2)Disconnect。等待MQTT客户端完成所做的工作,并与服务器断开TCP/IP会话。

    (3)Subscribe。等待完成订阅。

    (4)UnSubscribe。等待服务器取消客户端的一个或多个topics订阅。

    (5)Publish。MQTT客户端发送消息请求,发送完成后返回应用程序线程。

    五、MQTT协议数据包结构

     在MQTT协议中,一个MQTT数据包由:固定头(Fixed header)、可变头(Variable header)、消息体(payload)三部分构成。MQTT数据包结构如下:

    (1)固定头(Fixed header)。存在于所有MQTT数据包中,表示数据包类型及数据包的分组类标识。

    (2)可变头(Variable header)。存在于部分MQTT数据包中,数据包类型决定了可变头是否存在及其具体内容。

    (3)消息体(Payload)。存在于部分MQTT数据包中,表示客户端收到的具体内容。

    5.1 MQTT固定头

     固定报头,所有的MQTT控制报文都包含,可变报头与有效载荷是部分MQTT控制报文包含。 固定报头占据两字节的空间,具体见:

    在这里插入图片描述 固定报头的第一个字节分为控制报文的类型(4bit),以及控制报文类型的标志位,控制类型共有14种,其中0与15被系统保留出来,其他的类型具体见:

    类型 说明
    Reserved 0 系统保留
    CONNECT 1 客户端请求连接服务端
    CONNACK 2 连接报文确认
    PUBLISH 3 发布消息
    PUBACK 4 消息发布收到确认(QoS 1)
    PUBREC 5 发布收到(QoS2)
    PUBREL 6 发布释放(QoS2)
    PUBCOMP 7 消息发布完成(QoS2)
    SUBSCRIBE 8 客户端订阅请求
    SUBACK 9 订阅请求报文确认
    UNSUBSCRIBE 10 客户端取消订阅请求
    UNSUBACK 11 取消订阅报文确认
    PINGREQ 12 心跳请求
    PINGRESP 13 心跳响应
    DISCONNECT 14 客户端断开连接
    Reserved 15 系统保留

     固定报头的bit0-bit3为标志位,依照报文类型有不同的含义,事实上,除了PUBLISH类型报文以外,其他报文的标志位均为系统保留,PUBLISH报文的第一字节bit3是控制报文的重复分发标志(DUP),bit1-bit2是服务质量等级,bit0是PUBLISH报文的保留标志,用于标识PUBLISH是否保留,当客户端发送一个PUBLISH消息到服务器,如果保留标识位置1,那么服务器应该保留这条消息,当一个新的订阅者订阅这个主题的时候,最后保留的主题消息应被发送到新订阅的用户。

     固定报头的第二个字节开始是剩余长度字段,是用于记录剩余报文长度的,表示当前的消息剩余的字节数,包括可变报头和有效载荷区域(如果存在),但剩余长度不包括用于编码剩余长度字段本身的字节数。

     剩余长度字段使用一个变长度编码方案,对小于128的值它使用单字节编码,而对于更大的数值则按下面的方式处理:每个字节的低7位用于编码数据长度,最高位(bit7)用于标识剩余长度字段是否有更多的字节,且按照大端模式进行编码,因此每个字节可以编码128个数值和一个延续位,剩余长度字段最大可拥有4个字节。

    • 当剩余长度使用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)。

    总的来说,MQTT报文理论上可以发送最大256M的报文,当然,这种情况是非常少的。

    固定头存在于所有MQTT数据包中,其结构如下:

    5.1.1 MQTT数据包类型

    位置:Byte 1中bits 7-4。

    相于一个4位的无符号值,类型、取值及描述如下:

    5.1.2 标识位

    位置:Byte 1中bits 3-0。

     在不使用标识位的消息类型中,标识位被作为保留位。如果收到无效的标志时,接收端必须关闭网络连接:

    (1)DUP:发布消息的副本。用来在保证消息的可靠传输,如果设置为1,则在下面的变长中增加MessageId,并且需要回复确认,以保证消息传输完成,但不能用于检测消息重复发送。

    (2)QoS:发布消息的服务质量,即:保证消息传递的次数

            Ø00:最多一次,即:<=1
    
            Ø01:至少一次,即:>=1
    
            Ø10:一次,即:=1
    
            Ø11:预留
    

    (3)RETAIN: 发布保留标识,表示服务器要保留这次推送的信息,如果有新的订阅者出现,就把这消息推送给它,如果设有那么推送至当前订阅者后释放。
    5.1.3 剩余长度(Remaining Length)

    地址:Byte 2。

     固定头的第二字节用来保存变长头部和消息体的总大小的,但不是直接保存的。这一字节是可以扩展,其保存机制,前7位用于保存长度,后一部用做标识。当最后一位为1时,表示长度不足,需要使用二个字节继续保存。例如:计算出后面的大小为0

    5.2 MQTT可变头

     MQTT数据包中包含一个可变头,它驻位于固定的头和负载之间。可变头的内容因数据包类型而不同,较常的应用是作为包的标识。

    在这里插入图片描述

     只有某些报文才拥有可变报头,它在固定报头和有效负载之间,可变报头的内容会根据报文类型的不同而有所不同,但可变报头的报文标识符(Packet Identifier)字段存在于在多个类型的报文里,而有一些报文又没有报文标识符字段,具体见表格,报文标识符结构具体见图:

    报文类型 是否需要报文标识符字段
    CONNECT 不需要
    CONNACK 不需要
    PUBLISH 需要(如果QoS > 0)
    PUBACK 需要
    PUBREC 需要
    PUBREL 需要
    PUBCOMP 需要
    SUBSCRIBE 需要
    SUBACK 需要
    UNSUBSCRIBE 需要
    UNSUBACK 需要
    PINGREQ 不需要
    PINGRESP 不需要
    DISCONNECT 不需要

    5.3 Payload消息体

     Payload消息体位MQTT数据包的第三部分,包含CONNECT、SUBSCRIBE、SUBACK、UNSUBSCRIBE四种类型的消息:

    (1)CONNECT,消息体内容主要是:客户端的ClientID、订阅的Topic、Message以及用户名和密码。

    (2)SUBSCRIBE,消息体内容是一系列的要订阅的主题以及QoS。

    (3)SUBACK,消息体内容是服务器对于SUBSCRIBE所申请的主题及QoS进行确认和回复。

    (4)UNSUBSCRIBE,消息体内容是要订阅的主题。

    展开全文
  • MQTT协议-MQTT协议简介及协议原理

    万次阅读 多人点赞 2016-02-04 15:34:36
    MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的“轻量级”通讯协议,该协议构建于TCP/IP协议上,由IBM在1999年发布。MQTT最大优点在于,可以...

    MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅publish/subscribe)模式的“轻量级”通讯协议,该协议构建于TCP/IP协议上,由IBM在1999年发布。MQTT最大优点在于,可以以极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。做为一种低开销、低带宽占用的即时通讯协议,使其在物联网、小型设备、移动应用等方面有较广泛的应用。

    1. MQTT协议特点
    2. MQTT协议原理

     

    1. MQTT协议特点

    MQTT是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。其在,通过卫星链路通信传感器、偶尔拨号的医疗设备、智能家居、及一些小型化设备中已广泛使用。

    MQTT协议当前版本为,2014年发布的MQTT v3.1.1。除标准版外,还有一个简化版MQTT-SN,该协议主要针对嵌入式设备,这些设备一般工作于百TCP/IP网络,如:ZigBee。

    MQTT协议运行在TCP/IP或其他网络协议,提供有序、无损、双向连接。其特点包括:

    1. 使用的发布/订阅消息模式,它提供了一对多消息分发,以实现与应用程序的解耦。
    2. 对负载内容屏蔽的消息传输机制。
    3. 对传输消息有三种服务质量(QoS):
      • 最多一次,这一级别会发生消息丢失或重复,消息发布依赖于底层TCP/IP网络。即:<=1
      • 最少一次,这一级别会确保消息到达,但消息可能会重复。即:>=1
      • 只有一次,确保消息只有一次到达。即:=1。在一些要求比较严格的计费系统中,可以使用此级别
    4. 数据传输和协议交换的最小化(协议头部只有2字节),以减少网络流量
    5. 通知机制,异常中断时通知传输双方

     

    2. MQTT协议原理

    2.1 MQTT协议实现方式

    • 实现MQTT协议需要:客户端服务器端
    • MQTT协议中有三种身份:发布者(Publish)代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者
    • MQTT传输的消息分为:主题(Topic)负载(payload)两部分
      • Topic,可以理解为消息的类型,订阅者订阅(Subscribe)后,就会收到该主题的消息内容(payload
      • payload,可以理解为消息的内容,是指订阅者具体要使用的内容

     

    2.2 网络传输与应用消息

    MQTT会构建底层网络传输:它将建立客户端到服务器的连接,提供两者之间的一个有序的、无损的、基于字节流的双向传输。

    当应用数据通过MQTT网络发送时,MQTT会把与之相关的服务质量(QoS)和主题名(Topic)相关连。

     

    2.3 MQTT客户端

    一个使用MQTT协议的应用程序或者设备,它总是建立到服务器的网络连接。客户端可以:

    • 发布其他客户端可能会订阅的信息
    • 订阅其它客户端发布的消息
    • 退订或删除应用程序的消息
    • 断开与服务器连接

     

    2.4 MQTT服务器

    MQTT服务器以称为“消息代理”(Broker),可以是一个应用程序或一台设备。它是位于消息发布者订阅者之间,它可以:

    • 接受来自客户的网络连接
    • 接受客户发布的应用信息
    • 处理来自客户端的订阅和退订请求
    • 向订阅的客户转发应用程序消息

     

    2.5 MQTT协议中的订阅、主题、会话

    订阅(Subscription)

    订阅包含主题筛选器(Topic Filter)和最大服务质量(QoS)。订阅会与一个会话(Session)关联。一个会话可以包含多个订阅。每一个会话中的每个订阅都有一个不同的主题筛选器。

    会话(Session)

    每个客户端与服务器建立连接后就是一个会话,客户端和服务器之间有状态交互。会话存在于一个网络之间,也可能在客户端和服务器之间跨越多个连续的网络连接。

    主题名(Topic Name)

    连接到一个应用程序消息的标签,该标签与服务器的订阅相匹配。服务器会将消息发送给订阅所匹配标签的每个客户端。

    主题筛选器(Topic Filter)

    一个对主题名通配符筛选器,在订阅表达式中使用,表示订阅所匹配到的多个主题。

    负载(Payload)

    消息订阅者所具体接收的内容

     

    2.6 MQTT协议中的方法

    MQTT协议中定义了一些方法(也被称为动作), 来于表示对确定资源所进行操作。 这个资源可以代表预先存在的数据或动态生成数据,这取决于服务器的实现。通常来说,资源指服务器上的文件或输出。

    Connect,等待与服务器建立连接

    Disconnect,等待MQTT客户端完成所做的工作,并与服务器断开TCP/IP会话

    Subscribe,等待完成订阅

    UnSubscribe,等待服务器取消客户端的一个或多个topics订阅

    Publish,MQTT客户端发送消息请求,发送完成后返回应用程序线程

    http://itbilu.com/other/relate/4kHBsx_Pg.html

    展开全文
  • MQTT】在Windows下搭建MQTT服务器

    万次阅读 多人点赞 2016-09-29 18:15:02
    最近在项目中要使用MQTT协议,需要搭建一个MQTT服务器来进行调试,在网络上找了一天,找到的大多数都是MQTT客户端,最后发现这篇博客写的教程可以使用,特此记录。

    MQTT简介

    MQ 遥测传输 (MQTT) 是轻量级基于代理的发布/订阅的消息传输协议,设计思想是开放、简单、轻量、易于实现。这些特点使它适用于受限环境。该协议的特点有:

    • 使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合。
    • 对负载内容屏蔽的消息传输。
    • 使用 TCP/IP 提供网络连接。
    • 小型传输,开销很小(固定长度的头部是 2 字节),协议交换最小化,以降低网络流量。
    • 使用 Last Will 和 Testament 特性通知有关各方客户端异常中断的机制。
    • 有三种消息发布服务质量:
    • “至多一次”,消息发布完全依赖底层 TCP/IP 网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。
    • “至少一次”,确保消息到达,但消息重复可能会发生。
    • “只有一次”,确保消息到达一次。这一级别可用于如下情况,在计费系统中,消息重复或丢失会导致不正确的结果。

    前言

    最近在项目中要使用MQTT协议,需要搭建一个MQTT服务器来进行调试,在网络上找了一天,找到的大多数都是MQTT客户端,最后发现这篇博客写的教程可以使用,特此记录。

    寻找过程

    在寻找MQTT服务器的过程中,我发现的Mosquitto是一款「An Open Source MQTT v3.1/v3.1.1 Broker」——开源的MQTT代理服务器,其下也有Windows的安装包。

    Mosquitto

    但是我使用的是Win10 64位系统,这两个都下载安装后不是报错就是缺少dll文件,不能使用

    最后参考了前面博客说的,搭建了Apollo服务器,这里使用的Apollo 1.7.1。

    • 官网:http://activemq.apache.org/index.html
    • 下载地址:http://activemq.apache.org/apollo/download.html
    • 快速开始教程:http://activemq.apache.org/apollo/documentation/getting-started.html

    搭建MQTT服务器

    使用Apollo搭建MQTT服务器步骤:

    1. 下载Apollo服务器并解压,在CMD环境运行其工作目录下的...\bin\apollo.cmd,命令后面带上参数「create mybroker」,创建服务器实例。这里需要Java环境,系统环境变量下要有JAVA_HOME
    2. 创建实例之后会在bin目录下生成mybroker文件夹,其中 ...\etc\apollo.xml文件下是配置服务器信息的文件,...\etc\users.properties文件包含连接MQTT服务器时用到的用户名和密码,初始默认帐号是admin,密码password
    3. 进入...\mybroker\bin\ 目录,在CMD输入命令「apollo-broker.cmd run」,可以使用TAB键自动补全,运行后输出信息如下:

    MQTT服务运行信息

    其中我们要留意的:

    MQTT服务器TCP连接端口:tcp://0.0.0.0:61613

    后台Web管理页面:https://127.0.0.1:61681/或http://127.0.0.1:61680/

    登录服务器后,如果MQTT服务器有客户端连接,后台会显示如下

    后台

    Python的MQTT客户端

    在Python环境下有MQTT客户端包——paho-mqtt

    安装命令

    pip install paho-mqtt
    

    客户端代码清单

    下面是MQTT客户端代码清单

    import paho.mqtt.client as mqtt
    
    def on_connect(client, userdata, flags, rc):
        print("Connected with result code "+str(rc))
    
        client.subscribe("lettuce")
    
    def on_message(client, userdata, msg):
        print(msg.topic+" "+str(msg.payload))
    
    client = mqtt.Client()
    client.username_pw_set("admin", "password") # 必须设置,否则会返回「Connected with result code 4」
    client.on_connect = on_connect
    client.on_message = on_message
    
    HOST = "127.0.0.1"
    
    client.connect(HOST, 61613, 60)
    client.loop_forever()
    

    发布消息代码

    下面是往MQTT服务器发布消息的代码

    import paho.mqtt.publish as publish
    
    HOST = "127.0.0.1"
    
    publish.single("lettuce", "payload", hostname=HOST, port=61613,
                   auth={'username': "admin", 'password':"password"})
    

    更新

    2017年7月28日更新:

    最近发现了一款比较好的开源MQTT服务器:EMQ。Linux下部署教程可以参考这篇文章:EMQ初体验——在CentOS7上部署MQTT服务器

    Windows下部署可以到官网查阅相关资料。

    2017年8月15日更新:

    注意:后台Web管理页面被设置为只能本地访问,如果想用其他主机访问该管理页面,需要修改「http://127.0.0.1:61680/」为「http://0.0.0.0:61680/」。

    相关配置文件:apache-apollo-1.7.1\bin\mybroker\etc\apollo.xml,大约61行:

    <web_admin bind="http://127.0.0.1:61680"/>
    <web_admin bind="https://127.0.0.1:61681"/>
    

    好饿啊,早知道不做物联网了

    展开全文
  • 4G模块连接MQTT

    万次阅读 2020-06-28 09:56:36
    mqtt 作者:如果能编程回忆 最后修改时间:2020年6月12日 概述 Air724模块内置MQTT协议,提供AT,LUAT,CSDK,DTU可供选择使用,接口简单使用方便。 MQTT简介 优势:长连接,低带宽,高可靠。 实用场景:需要服务器...
  • MQTT MQTTnet 实现

    2019-01-02 13:54:28
    MQTTnet .NET库实现的MQTT 客户端和服务端代码,源程序。可以执行。
  • 目录 MQTT(一)C#使用 MQTTnet 快速实现 MQTT 通信(文末有完整Demo下载) MQTT(二)在windows64位上安装Python环境 ...MQTT(五)EMQ开源MQTT消息服务器 1 什么是 MQTTMQTT(Message Que...
  • MQTT调试工具,用于MQTT协议联调联试,使用方便,画面简洁清晰,需要键入地址及端口号,ID/用户名及密码后连接,能够用来进行十六进制显示和ASCII显示,可以订阅MQTT topic!
  • 【实例简介】MQTTnet .NET库...【实例截图】【核心代码】MQTT└── MQTT├── MQTT│ ├── MQTTServer.csproj│ ├── Program.cs│ ├── bin│ │ └── Debug│ │ └── netcoreapp2.0│ │ ├── M...
  • MQTT源码库:eclipse-paho-mqtt-c-src-1.2.0 测试工具:MQTTBox MQTT服务器:阿里云部署EMQX VC MFC程序运行图示: 一、编译MQTT生成dll lib 1、下载MQTT源码库:eclipse-paho-mqtt-c-src 下载github地址:...
  • Qt开发技术:mqtt介绍、QtMqtt编译和开发环境搭建

    万次阅读 多人点赞 2019-06-11 20:30:38
    原博主博客地址:https://blog.csdn.net/qq21497936 ... 目录 MQTT协议简介 设计原则 特点 发布/订阅者模式 MQTT服务器 MQTT协议中的方法 Qt搭建MQTT编程环境 介绍 下载mqtt 编译mqtt(注意:使...
  • 【协议】MQTT、CoAP、HTTP比较,MQTT协议优缺点

    万次阅读 多人点赞 2019-04-17 20:27:50
    从这几个层面进行比较与描述: 1. 协议栈: MQTT: TCP 长链接, CoAP: UDP 低功耗短连接, HTTP: TCP 2. 请求方式 MQTT: 发布订阅, CoAP: request...MQTT: CoAP: HTTP: 4. 使用特点与使用场...
  • C#使用 MQTTnet 快速实现 MQTT 通信 Demo

    热门讨论 2019-03-14 10:15:44
    此Demo对应本人博客文章《MQTT(一)C#使用 MQTTnet 快速实现 MQTT 通信》 开发环境Win7 + vs2017
  • 最新版MQTT调试助手 MQTT 最新1.0 版本
  • java连接MQTT服务器(Springboot整合MQTT)

    万次阅读 多人点赞 2020-01-13 19:38:18
    硬件采集的数据传入EMQX平台(采用MQTT协议),java通过代码连接MQTT服务器,进行采集数据接收、解析、业务处理、存储入库、数据展示。 MQTT 是基于发布(Publish)/订阅(Subscribe)模式来进行通信及数据交换的。 二、...
  • MQTT客户端

    2018-05-25 16:55:53
    MQTT客户端实现; VS环境,可以直接使用;用于测试,客户端编写均可
  • Qt开发MQTT(一) 之Qt官方Qt MQTT

    万次阅读 多人点赞 2020-03-05 22:35:31
    Qt开发MQTT程序有两种方式,一个是Qt官方提供的基于MQTT的封装,一个是第三方(EMQ)开发的用于Qt调用MQTT的接口,二者使用方法大同小异,并且均提供了源码。那么,这里先来介绍第一种,如基于Qt官方提供的封装来...
  • 物联网之mqtt实现(emqx + springboot +mqtt,附完整源码) 包括centos安装emqx,springboot集成mqtt, 发送消息与接收消息例子,实例讲解,附完整源码。
  • mqtt.js库,下载后可以用找我要源码和压缩文件(mqtt.min.js),有问题随时请教
  • 使用ssl连接腾讯MQTT服务器,使用了cert验证,可根据自己需要编写回调函数,操作lcd或者其他的硬件,注释比较少,功能完全没问题,不适合新手阅读,适合对框架有一定了解的人使用。
  • mqtt.MqttClient

    千次阅读 2018-07-11 08:31:31
    1.消息处理handler,实现MqttSimpleCallback,也可以对高级回调接口实现...package cn.smartslim.mqtt.demo.wmqtt; import com.ibm.mqtt.MqttSimpleCallback; //简单回调函数,处理server接收到...
  • MQTT协议 C#客户端(基于M2MQTT)

    万次阅读 热门讨论 2016-07-13 12:14:41
    1、引入M2MQTT的dll库文件 点击此处下载M2Mqtt.Net.dll 2、建立客户端连接并订阅 //创建客户端实例 MqttClient client = new MqttClient(IPAddress.Parse(MQTT_BROKER_ADDRESS)); //主机为IP时 MqttClient ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 36,457
精华内容 14,582
热门标签
关键字:

mqtt