官网英文参考: http://activemq.apache.org/apollo/documentation/mqtt-manual.html





 MQTT协议

Apollo允许客户端通过开放的MQTT协议连接。该协议主要是用在资源有限的驱动上,以及网络不稳定的情况下使用,是一个订阅、发布模型。这种驱动通常不适用类似http,stomp这类基于文本,或者类似openfire,AMQP等传统二进制协议。MQTT是一个简介的二进制协议,适用这类驱动资源受限,而且是不稳定的网络条件下。

之前的稳定发布版本中,MQTT是作为一个Apollo的一个插件提供的。但是现在,这个插件已经变为开发项目的一部分。MQTT在Apollo中已经不需要其他配置文件或者是第三方插件支持了。

MQTT是一个线路层的协议,任何实现该协议的客户端都可以连接到Apollo。当然也可以整合其他MQTT兼容的消息代理中。

更多有关MQTT协议内容,参考 the MQTT Specification

 MQTT协议配置

为了开始使用MQTT协议,首先使用MQTT3.1协议的客户端,连接到Apollo正在监听端口。Apollo会做协议检测,而且自动识别MQTT连接,而且将连接作为MQTT协议处理。你不必要为MQTT协议打开一个端口(STomp,Openfire,AMQP等都是自动识别)。如果你一定指定连接的协议,有下面两种方式:你可以选择不用协议识别,而是为MQTT指定连接:

<connector id="tcp" bind="tcp://0.0.0.0:61613" protocol="mqtt"/> 
 

   或者你可以限制哪种协议可以被自动识别。通过下面的<detece>配置方式: 
 

   <connector id="tcp" bind="tcp://0.0.0.0:61613"> 
 

     <detect protocols="mqtt openwire" /> 
 

   </connector> 
 

   <detect> 下protocols 对应的参数通过空格来隔开支持的通信协议。如果只支持一种协议,就不要空格,默认情况下对任何协议生效。 
 

   如果你想调整MQTT默认设置,在apollo.xml文件中有一个<connector> 元素,通过MQTT参数配置: 
 

   <connector id="tcp" bind="tcp://0.0.0.0:61613"> 
 

     <mqtt max_message_length="1000" /> 
 

   </connector> 
 

   MQTT元素支持下面几个参数: 
 
max_message_lengthprotocol_filtersdie_delay

   mqtt 配置元素也可以用来控制目的消息头的解析。下面是支持的参数: 
 
queue_prefixpath_separator
•  : used to separate segments in a destination name; default: 
/(用来分割目的地名称)any_child_wildcard
•  : indicate all child-level destinations that match the wildcard; default: 
+(识别子目录)any_descendant_wildcard
•  : indicate destinations that match the wildcard recursively; default:
#(目标地址通配符)regex_wildcard_startregex_wildcard_endpart_pattern
•  : allows you to specify a regex that constrains the naming of topics. (你可以指定正则表达规则)default: 
[ a-zA-Z0-9\_\-\%\~\:\(\)]+

    Client 可用函数库 
 

   Apollo 支持MQTT3.1 协议,下面是可用的Clients: 
 
• Java : mqtt-client, MeQanTT

• C : libmosquitto

• Erlang : erlmqtt, my-mqtt4erl

• .NET : MQTTDotNet, nMQTT

• Perl : net-mqtt-perl, [anyevent-mqtt-perl]https://github.com/beanz/anyevent-mqtt-perl()
• Python : nyamuk

• Ruby : mqtt-ruby, ruby-em-mqtt

• Javascript : Node.js MQTT Client

• Delphi : TMQTTCLient

• Device specific: Arduino, mbed, Nanode, Netduino

   如果要找到新支持的Clients ,可以检索: 
  the MQTT website for its software 
 

   在目录example 目录下,你可以找到一些例子,实现了与broker之间收发。 
 

    connecting 
 

   为了确保broker配置文件的安全,所以只允许一个admin 用户连接,默认的用户名和密码是:admin ,password. 
 
see  
  the section on Virtual Hosts in the user guide 
  ),以至于默认情况下虚拟主机已经被使用了。通常第一虚拟主机定义在apollo.xml文件中。 
 

    Destination 类型 
 

   MQTT协议是订阅,发布协议,是不允许真正的利用队列点对点的消息收发。因此Apollo仅允许利用主题,还进行MQTT消息发送。订阅的概念和持久的主题订阅 和其他协议提到的有些类似,同时也被MQTT CONNECT 框架的clean session属性控制。 
 

    Clean Sessions 
 

   但一个Client 发送一个连接,这个连接中clean session 被设置为false,那么之前连接中有相同Client_id 的session 将会被重复使用。这就意味着Client断开了,订阅依然能收到消息。这就等同与同Apollo建立一个长订阅。 
 

   如果 clean session 设置为true ,那么新session就开始了,其他的session会慢慢消失,删除。这就是Apollo中定义的普通的主题订阅。 
 

    Topic Retained Messages 
 

   如果消息被发布的同时retain 标记被设置,消息将被主题记住,以至于新的订阅到达,最近的retain 消息会被发送到订阅者。比如说:你想发布一个参数,而且你想让最新的这个参数发布到总是可用的订阅了这个主题的客户端上,你就设置在PUBLISH 框架上设置retain 标签。 
 

   注意:retained 消息 不会被设置成retained 在 QoS设置为零的broker 重启过程中。 
 
 Last Will and Testament Message

   当Client第一次连接的时候,有一个will 消息和一个更QoS相关的消息会跟你有关。will消息是一个基础消息,这个基础消息只有在连接异常或者是掉线的时候才会被发送。一般用在你有一个设备,当他们掉了的时候,你需要知道。所以如果一个医疗Client从broker掉线,will消息将会作为一个闹钟主题发送,而且会被系统作为高优先级提醒。 
 
 Reliable Messaging

   MQTT协议允许Client 发布消息的时候指定Qos参数: 
 
• At Most Once (QoS=0)
• At Least Once (QoS=1)
• Exactly Once (QoS=2)

    最多一次 
 

   这个设置时推送消息给Client,可靠性最低的一种。如果设置Qos=0,那broker就不会返回结果码,告诉你他收到消息了,也不会在失败后尝试重发。这有点像不可靠消息,如JMS。 
 

    至少一次 
 

   该设置会确保消息会被至少一次推送到Client。如果推送设置为至少推送一次,Apollo会返回一个回调函数,确保代理已经收到消息,而且确保会确保推送该消息。如果Client 将发布了一个Qos=1的消息,如果在指定的时间内没有收到回复,Client会希望重新发布这个消息。所以可能存在这种情况:代理收到一个需要推送的消息,然后又收到一个消息推送到同一个Client。所以如果传输过程中PUBACK丢失,Client会重新发送,而且不会去检测是否是重发,broker就将消息发送到订阅主题中。 
 

    恰好一次 
 

   该设置是可靠等级最高的。他会确保发布者不仅仅会推送,而且不会像Qos=1 那样,会被接收两次。当然这个设置会增加网络的负载。当一个消息被发布出去的时候,broker会保存该消息的id,而且会利用任何长连接,坚持要把该消息推送给目标地址。如果Client收到PUBREC 标志,那就表明broker已经收到消息了。 这个时候broker会期待Client发送一个PUBREL 来清除session 中消息id,broker如果发送成功就会发送一个PUBCOMP通知Client。 
 
 Wildcard Subscriptions

   通配用在主题的目标地址中。这能实现一个主题发送到多个用户,或者多层用户中。 
 
/+#

   比如通配可能这样来用: 
 
PRICE/#PRICE/STOCK/#PRICE/STOCK/NASDAQ/+PRICE/STOCK/+/IBM
 Keep Alive

   Apollo只有在Client指定了CONNECT的KeepAlive 值的时候,才会设置保持连接、心跳检测。如果one Client指定了keepalive,apollo 将会使用1.5*keepalive值。这个在MQTT中有说明。 
 
 Destination Name Restrictions

   路径名称限制了使用(a-z, A-Z, 0-9, _, - %, ~, :, ' ', '(', ')' ,. )字符,通配符(*)在复杂的分隔符中。而且确保使用utf-8来编译你的URL。