物联网(IoT)常用协议MQTT及MQTT Broker之mosquitto的基础使用

大数据、人工智能、物联网,这些都是互联网将来重点发展的规划方向。大数据分析你的行为,如在淘宝、京东上经常看或者搜一类产品,他就会在首页智能的向你推这类的丰富产品,在新闻、百度广告位等都是有应用的(所以自己的手机不要随意给别人看,通过一些你常用的APP就可以看出来你的一些个人隐私信息,隐私啊!)。人工智能让生活更有趣,但是人工智能目前更多的是一个噱头,发展还是有待走向成熟化的。至于物联网,现在很多公司都是有雏形产品的,一些巨头公司已经提供了对应的处理方案,如阿里的IoT平台、华为的IoT平台、小米的物联网相关产品等。至于物联网是做什么的呢。下面来说说我的理解。

物联网的理解

声明:下面所说为个人理解,大白话,不喜勿喷!

首先大概知道一下物联网的概念。物联网是身边的事物和人之间通过网络的关联,程序的计算,达到物的智能化和可操控便捷性。能组织出来这句话不容易,三年后我再看,估计我都不知道在说什么,下面用例子来说明。

如家里有空调、热水器、冰箱等设备,上班出门后发现空调或者热水器没有关,这个时候除了回家关没有其他的办法。如果使用物联网技术,将家里的空调、热水器等设备连到网络上,在手机上可以用APP看到家里电器的运行情况,然后通过APP来操作这些设备的启停。这个利用的范围是比较广的。如APP操作汽车的启停,冬天或者夏天在上车前先调好车内的温度(目前很多品牌的汽车都已经实现);如智能窗门,下暴雨的时候可以通过APP将窗户关上,防止家里进水;再比如在外忙了一天,在地铁上将家里的空调热水器调好,回家洗个热水澡,吹着空调岂不爽歪歪。

至于这种技术怎么实现,目前在车上面是需要购买流量,变相的说就会在车上安装一个网络,APP通过网络请求来控制汽车的部分功能。对于家里的家电也是同样,家电通过无线网或者其他局域网,最终连接到网络中,APP通过发送指令来控制家电的动作。

看下面粗略的示意图:

物联网大概是干什么的已经知道了,以本人表达能力只能这样了,凑合着看吧!

这篇文章的主题是说MQTT交互的协议以及MQTT的代理(MQTT broker)的内容,说上面的内容就是为了让我们更好的理解MQTT从中起到的作用。下面进入正题。

MQTT协议

概念:MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。它工作在 TCP/IP协议族上,是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议,为此,它需要一个消息中间件。(来自百度百科)

MQTT是一个通讯协议,和http是属于同一类,只是协议的定义不一样和具体的通讯机制有所不同。MQTT是基于消息队列的机制,需要使用MQTT代理。如果用过rabbitMQ的会知道,他们使用的是AMQP协议。只是了解MQTT概念还是不够的。

特性:

  • 使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合。
  • 对负载内容屏蔽的消息传输。
  • 使用TCP/IP提供网络连接。

三种消息发布服务质量:

  • 0: “至多一次”,消息发布完全依赖底层 TCP/IP 网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送;
  • 1:“至少一次”,确保消息到达,但消息重复可能会发生;
  • 2:“只有一次”,确保消息到达一次。这一级别可用于如下情况,在计费系统中,消息重复或丢失会导致不正确的结果。

MQTT中的三种身份:

  • 发布者(publish):发布消息到代理服务器
  • 代理服务(broker):接收发布者的消息,将消息分发给消息的订阅者
  • 订阅者(subscribe):在代理上订阅消息

MQTT消息组成部分:

  • Topic(主题),可以理解为消息的类型,订阅者订阅(Subscribe)后,就会收到该主题的消息内容(payload)
  • payload(负载),可以理解为消息的内容,是指订阅者具体要使用的内容。

MQTT代理(MQTT broker)mosquitto的安装

MQTT的代理有很多,有不同语言写的,用的比较多的是mosquitto,这里也就以这个为例来写Demo。下面依次进行。

  • 下载、解压

    1
    2
    wget http://mosquitto.org/files/source/mosquitto-1.5.tar.gz
    tar -zxvf mosquitto-1.5.tar.gz
  • 编译安装

    1
    2
    cd mosquitto-1.5
    make && make install
  • 建立软连接

    1
    ln -s /usr/local/lib/libmosquitto.so.1 /usr/lib/libmosquitto.so.1
  • 更新动态连接库

    1
    ldconfig
  • 启动

    1
    2
    # -c用来指定配置文件的位置
    mosquitto -c /etc/mosquitto/mosquitto.conf

注意:如果在启动的时候报错,错误信息是:Error: Invalid user 'mosquitto',不要慌,执行下面的命令,然后重新执行启动命令即可。

1
useradd mosquitto

这样mosquitto的安装、启动都已经完成啦。至于里面的一些详细配置,服务如何优化这里不讨论,其实我也不会。前期了解,真实使用再深入。

关于启动mosquitto还要说一下,如果直接使用上面说的命令启动会有个问题,不能在后台运行。可以使用下面的命名解决:

1
2
# 日志的位置可以自己指定,这里使用的日志路径:/usr/local/mos/mos_log.log
nohup mosquitto -c /etc/mosquitto/mosquitto.conf > /usr/local/mos/mos_log.log 2>&1 &

下面就要讨论一下业务代码如何连接mosquitto,将业务链串联起来,应用到实际业务场景。

Java连接mosquitto发布和订阅消息

这一步写一下思想,不具体写太多东西,因为连接第三方服务基本都是一样,IP、端口、请求出参入参等等。后续会在示例代码中具体写出对应的代码实现。

  • 首先是在配置文件中配置对应的ip、端口等信息;
  • 在业务系统启动的时候自动初始化MqttClient客户端实例,在初始化的时候就已经和mosquitto建立了连接关系;
  • 上面建立的连接关系可以是发布消息端、订阅消息端以及同时包含发布和订阅;
  • 在建立连接的时候会涉及到一个callback类,这个是回调使用,包括连接丢失回调、消息送达回调、消息接收回调方法,这里面做具体的业务逻辑处理。

主要的类有两个,分别是IotMqttClientMqttClientCallBack。分别用来发送请求和接收请求回调或者订阅的消息。具体不多说。代码见文末。

命令方式发布和订阅消息

上面是代码的方式连接mosquitto,系统初始化订阅消息,然后通过接口的调用发布消息,实现消息发布和订阅的流程测试操作,如果是安装好mosquitto后想试试服务是否已经完备,可以使用命令的方式直接操作。(启动mosquitto就不说了)

  • 首先要打开两个窗口(连接linux机器的两个终端窗口),一个窗口用来订阅主题,一个窗口用来发布消息;

  • 订阅命令:

    1
    2
    # 订阅主题为itcrud的消息队列
    mosquitto_sub -t 'itcrud'
  • 发布命令:

    1
    2
    # 发布消息,主题是itcrud,内容是blog.itcrud.com test mosquitto
    mosquitto_pub -t 'itcrud' -m 'blog.itcrud.com test mosquitto'
  • 上面两步操作结束后,订阅消息的界面会打印出发布命令中的消息内容blog.itcrud.com test mosquitto

mosquitto的用户控制

上面说的都是直接连就可以,不需要任何鉴权信息,这样很不安全,作为测试用用还可以,在生产环境就不行啦。很容易被攻击。

  • 配置文件mosquitto.conf修改第一个位置是根据allow_anonymous查找,然后修改为allow_anonymous false,表示关闭匿名登录

  • 配置文件mosquitto.conf修改第二个位置是根据password_file查找,然后修改为password_file /etc/mosquitto/pwfile.conf,指定存储用户名密码文件的位置,在/etc/mosquitto目录下有一个默认的pwfile.example,将文件名改成conf后缀,如果偷懒不改也是可以的,保持配置的用户密码文件和实际文件一致即可。

  • 添加用户名和密码

    1
    2
    3
    4
    5
    6
    7
    # 使用-c会将当前pwfile.conf里面的用户名密码信息都删除,然后新建一条,建议在首次添加的时候使用
    # 使用-b表示追加用户名密码信息,对之前已经存在的信息不影响
    # 命令执行后会提示输入对应的密码,输入两次
    # 命令格式:mosquitto_passwd [-c] [密码文件的位置] [用户名]
    mosquitto_passwd -c /etc/mosquitto/pwfile.conf itcrud
    # 命令格式:mosquitto_passwd [-b] [密码文件的位置] [用户名] [密码]
    mosquitto_passwd -b /etc/mosquitto/pwfile.conf mos 123456
  • 删除用户

    1
    2
    3
    4
    5
    # 使用-c会将当前pwfile.conf里面的用户名密码信息都删除,然后新建一条,建议在首次添加的时候使用
    # 使用-b表示追加用户密码信息,对之前已经存在的信息不影响
    # 命令执行后会提示输入对应的密码,输入两次
    # 格式:mosquitto_passwd [-D] [密码文件的位置] [用户名]
    mosquitto_passwd -D /etc/mosquitto/pwfile.conf itcrud

用户控制的信息就这么多,需要注意的是添加用户的两个命令,-c的命令要慎重,否则可能导致之前的用户都被删除,如果再没有备份,那就悲剧啦。

另外用户鉴权加上后,在使用mosquitto命令发布、订阅消息的时候就要加上用户信息啦,如下:

1
2
mosquitto_sub -t 'itcrud' -u itcrud -P 123456
mosquitto_pub -t 'itcrud' -m 'blog.itcrud.com test mosquitto' -u itcrud -P 123456

mosquitto的权限控制

用户可以创建,而且可以创建很多用户,那么此时就需要控制这些用户的权限,那些可以发布消息,那些只能订阅不能发布等。

配置信息的格式如下:

1
2
user [用户名]
topic <write,read> [topic名称]

表达式很简单,唯一需要注意就是topic命令后的三个值,下面解释一下。

  • write:表示发布消息的权限
  • read:表示订阅的权限
  • 空值:表示既可以发布也可以订阅

这个配置信息是配置在aclfile.conf文件中,在/etc/mosquitto目录下有一个aclfie.example,将其名字改成conf后缀。然后将下面的内容添加到配置文件中。

1
2
3
4
5
6
7
# itcrud、mos用户已经在上一步用户控制里添加,其中的'#'通配符,表示所有,admin表示管理员
user itcrud
topic write /topic/itcrud/#
user mos
topic read /topic/itcrud/#
user admin
topic /topic/#

最后就是把aclfile.conf文件配置到mosquitto.conf配置文件中。在mosquitto.conf文件中找到acl_file,然后修改为acl_file /etc/mosquitto/aclfile.conf

总结

  • 首先了解一下物联网的基本概念,以及个人对物联网的理解
  • 第二说说物联网中常用的协议MQTT的概念
  • 第三说说MQTT中使用的代理,并详细介绍了常用的代理mosquitto的安装
  • 第四说说mosquitto的发布、订阅消息的命令,然后提供了Java实现连接mosquitto的代码,代码没有具体说,想研究的可以下载自己看,很简单
  • 第四说说mosquitto用户鉴权控制,如果配置配置文件信息
  • 第五说说mosquitto对用户权限控制,如何配置用户发布、订阅的权限

思路还算清晰,不能保证文章里面没有错误存在或者表达不详细的部分,如果发现欢迎留言指正。

示例源码

码云(gitee):https://gitee.com/itcrud/iot-mqtt

GitHub:https://github.com/IT-CRUD/iot-mqtt


本文作者:IT-CRUD
原文地址:http://blog.itcrud.com/blogs/2019/02/iot-mqtt-mosquitto-original
版权归作者所有,转载请注明出处

支付宝 微信

如果文章对你有帮助,欢迎点击上方按钮打赏作者