您的位置:首页 > 产品设计 > UI/UE

MQTT协议与mosquitto的安装使用

2016-06-11 13:04 495 查看
MQTT (Message Queuing Telemetry Transport,消息队列遥测传输) 是一种标准化的发布/订阅消息传输协议。它是一种非常轻量级的协议,由于对带宽需求很低,从而成为了 M2M 通信或物联网应用的理想选择,现在已经成为这类场景最常见的协议之一。

发布/订阅

发布订阅模式比轮询的效率高很多。发布订阅是MQTT协议的核心,除了基于同一个消息代理的发布者和订阅者之外,还有一些其它节点围绕着该消息代理呈星型拓扑分布。这个模型与标准的客户端/服务器迥然不同,一开始看似有些奇怪,但它提供的去耦能力在很多情况下都有巨大的优势。

客户端可以发布或订阅特定的主题(topic,有些类似信息主题),根据使用它们的消息代理来决定谁会收到信息。MQTT 的主题有特定的语法,使用斜杠(/)作为分隔符,整体呈层次结构,非常类似 URL 中的路径格式,因此厨房中的温度传感器也许会发布到类似
sensors/temperature/home/kitchen
这样的主题。

我们看一个例子:想象一下有一个网络,将全世界的温度传感器连接起来,提供气象服务。所有这些传感器保持与某个消息代理中间件相连接,每隔10分钟报告一次当前的温度。他们基于自身位置按照下面的格式向特定主题发布信息:

sensors/temperature/{country}/{city}/{street name}


那么在伦敦贝克街(Baker Street)的某个传感器就会向“sensors/temperature/uk/london/baker_street”发布一条包含当前温度的信息。



气象服务需要保证历史温度数据库的数据最新,因此创建了订阅到 MQTT主题的数据库服务,数据库服务会在收到最新温度信息时发出提示。不过这里存在一个问题:数据库服务需要了解到全世界所有的温度传感器,而将每个传感器订阅到独立的主题会非常复杂,幸好 MQTT 有相应的解决方案:通配符(wildcards)。

通配符

在 MQTT 中有两个可用的通配符,分别是+和#,+表示匹配单一层级中的任意主题,#表示匹配任意数量的层次。因此在全球温度数据库中可能会有订阅到 sensors/temperature/# 的服务,它能从全世界的任何一个传感器接收温度读数。但如果英国政府想要在自己的温度服务中利用这些数据,只要订阅到 sensors/temperature/uk/# ,就可以限制范围,只接受英国的传感器读数。如果某个服务想要接收某个特定位置所有类型的传感器数据,可以使用类似这样的格式:

sensors/+/uk/london/bakerstreet_


正如你所见,这是一个极优秀的模块化系统,添加新的传感器与数据库只是小事一桩。而且该系统在性能方面也很优秀,MQTT 消息代理可以高度并行化并采用事件驱动,从而使得单个消息代理可以轻易扩展到每秒处理数万条信息的级别。

服务质量(QoS)

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

QoS Level 0:至多一次

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

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

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

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

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



“临终遗嘱”信息

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

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

安全性

MQTT(及通常的物联网设备)的安全性是一个相当大的主题,之后我们会详加描述,不过在本文中仅涉及两个主要的安全性功能:身份验证与加密。

身份验证是通过在 MQTT 连接包中发送用户名与密码来实现,几乎所有消息代理与客户端在实现时都支持这一功能。但由于信息太容易被拦截,为了避免,应当尽可能地使用安全传输层协议(TLS)。

协议本身未提供加密功能,但由于 MQTT 是在 TCP 上层运行的,我们可以很容易地利用 TLS 来提供加密连接。但这确实增加了发送与接收信息的计算复杂性,不但在约束系统中会造成问题,还会影响消息代理的性能。稍后我们会就这个问题进行更多讨论。

消息代理软件

有许多不同方式实现的可用消息代理,最常见的系统包括:

- Mosquitto —— 这是最早在生产环境中可用的消息代理之一,以 C 语言编写,提供多种配置与高性能。

- Mosca —— 以 Node.js 编写,可嵌入 Node 应用或以独立可执行文件的形式运行。由于配置简单并具有可扩展性,它也是我们最喜欢的消息代理,具有高性能的优点。

- RSMB —— IBM 对 MQTT 协议的实现,也是最不常用的选项之一,不过它是一个用C语言编写的成熟系统。

- HiveMQ —— HiveMQ 是一种相对较新的消息代理,面向企业环境,在博客上有很多关于 MQTT 不错的信息。

Mosquitto安装和使用

Mosquitto目前的最新版本为1.4.9。

安装编译的依赖库

sudo apt-get install libssl-dev
sudo apt-get install libc-ares-dev
sudo apt-get install uuid-dev


源码下载

wget http://mosquitto.org/files/source/mosquitto-1.4.9.tar.gz[/code] 
解压

tar zxfv mosquitto-1.4.9.tar.gz


进入目录

cd mosquitto-1.4.9

编译

make -j4

安装

sudo make install

简单测试一下

一个完整的MQTT示例包括一个代理器,一个发布者和一个订阅者。测试分为以下几个步骤:

启动服务mosquitto。

订阅者通过mosquitto_sub订阅指定主题的消息。

发布者通过mosquitto_pub发布指定主题的消息。

代理服务器把该主题的消息推送到订阅者。

测试时在同一机器上。

a.启动代理服务

mosquitto -v

【-v】打印更多的调试信息

b.订阅主题

mosquitto_sub -v -t sensor

【-t】指定主题,此处为sensor

【-v】打印更多的调试信息

c.发布内容

mosquitto_pub -t sensor -m 13

【-t】指定主题

【-m】指定消息内容

在测试的过程中,如果出现
error while loading shared libraries: libmosquitto.so.1: cannot open shared object file: No such file or directory
的错误。

执行下面的命令

sudo ldconfig


如果还是出现则在执行
sudo ldconfig
之前执行

sudo ln -s /usr/local/lib/libmosquitto.so.1 /usr/lib/libmosquitto.so.1


运行信息

zhou@zhou-K42JE:~$ mosquitto -v
1465620993: mosquitto version 1.4.9 (build date 2016-06-11 11:42:07+0800) starting
1465620993: Using default config.
1465620993: Opening ipv4 listen socket on port 1883.
1465620993: Opening ipv6 listen socket on port 1883.
#代理服务运行

1465620993: New connection from 127.0.0.1 on port 1883.
1465620993: New client connected from 127.0.0.1 as mosqsub/11776-zhou-K42J (c1, k60).
1465620993: Sending CONNACK to mosqsub/11776-zhou-K42J (0, 0)
1465620993: Received SUBSCRIBE from mosqsub/11776-zhou-K42J
1465620993:     sensor (QoS 0)
1465620993: mosqsub/11776-zhou-K42J 0 sensor
1465620993: Sending SUBACK to mosqsub/11776-zhou-K42J
#一个订阅者连接到代理服务

1465621005: New connection from 127.0.0.1 on port 1883.
1465621005: New client connected from 127.0.0.1 as mosqpub/12021-zhou-K42J (c1, k60).
1465621005: Sending CONNACK to mosqpub/12021-zhou-K42J (0, 0)
#发布者连接到代理服务
1465621005: Received PUBLISH from mosqpub/12021-zhou-K42J (d0, q0, r0, m0, 'sensor', ... (2 bytes))
#代理服务接受到发布者的消息
1465621005: Sending PUBLISH to mosqsub/11776-zhou-K42J (d0, q0, r0, m0, 'sensor', ... (2 bytes))
#代理者将发布者发布的主题信息发送给订阅了这个主题的订阅者
1465621005: Received DISCONNECT from mosqpub/12021-zhou-K42J
1465621005: Client mosqpub/12021-zhou-K42J disconnected.
#发布者与代理服务断开连接


开始为代理启动在本地的1883端口,然后新的连接,是一个订阅者。然后一个发布者发布一条消息,然后代理将信息发送给订阅者。

参考资料

实用简介:MQTT协议及其在物联网中的应用

MQTT学习笔记——MQTT协议体验 Mosquitto安装和使用
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: