一、MQTT协议简介
MQTT 是一个基于发布/订阅模式的消息传输协议。它具有轻量级、开放、简单,易于实现,通信带宽要求低等特点。这些特点使得它对机器与机器的通信(M2M)以及物联网应用(IoT)来说是很好的选择。它还被应用到手机APP和Web应用中。
MQTT于1999年由Andy Stanford-Clark(IBM)和Arlen Nipper(Arcom,现为Cirrus Link)发明,最初的应用是为了以最小的电池损耗和最小网络带宽将石油管道数据通过卫星进行传输。在MQTT最初版本发布3年后,OASIS开源组织接管MQTT的标准化制定工作。MQTT如今的最新版本为MQTT3.1.1,相比MQTT3.1的变动很小,但还是鼓励使用3.1.1版本,3.1.1已经成为了ISO标准。
客户端/服务器模式 vs 发布/订阅模式
传统的网络通信模式几乎都是基于客户端/服务器模式的:客户端直接和一个服务端建立连接,通信来获取数据,数据源和数据目的地双方直接连接。比如在Web应用程序中,浏览器直接和Web服务器通过HTTP协议通信,浏览器需要知道服务器的IP和端口号。
而发布/订阅模式解耦了客户端,客户端分为2种角色:发布者(Publisher)和订阅者(Subscriber)。每一个发布者(Publisher)可以发送不同类型的消息,我们把消息的类型叫做主题(topic),MQTT通信中的消息都属于某一个主题 ,而只有订阅了这个主题的订阅者(Subscriber)才能收到属于这个主题的消息。发布者和订阅者不需要在意和知道对方的存在(不需要知道对方的IP和端口),也不需要直接与对方建立连接。因为通信中存在着一个叫代理(MQTT broker)的第三种角色,也可以叫MQTT服务器(MQTT server)。
发布者、订阅者只需要知道MQTT 服务器的IP和端口即可,并和它直接建立连接通信。MQTT代理作为消息的中转,它过滤所有接受到的消息,并按照一定的机制(MQTT标准规定是基于主题的消息过滤派发方式,而具体的MQTT服务器软件也提供了其他的派发方式)分发它们,使得所有注册到MQTT代理的订阅者只接收到他们订阅了的消息,而不会收到他不关心的消息。
当发布者发布一条消息的时候,他必须同时指定消息的主题和消息的负载。MQTT代理在收到发布者发过来的消息时,无需访问消息负载,他只是访问消息的主题信息,然后根据这主题派发给订阅者。需要注意的是,一个客户端可以同时既当发布者又当订阅者。比如一个开发板连接了一盏LED灯,它可以发布灯的暗/亮状态信息,也可以从其他节点订阅对灯的控制消息。
二、搭建MQTT服务器
1、安装
sudo apt-add-repository ppa:mosquitto-dev/mosquitto-ppa #添加源到软件仓库
sudo apt-get update #更新软件仓库列表
sudo apt-get install mosquitto #安装mosquitto
2、试运行
sudo service mosquitto status #查看运行状态
sudo service mosquitto start #启动服务
sudo service mosquitto stop #停止服务
3、将Linux的TCP端口(mosquitto默认为1883)打开
Ubuntu开放指定端口:一般情况下,ubuntu安装好的时候,iptables会被安装上,如果没有的话那就安装上吧!
3.1、安装:
sudo apt-get install iptables
3.2、添加规则(中间的 1883 为所需要开放的端口)
iptables -I INPUT -p tcp --dport 1883 -j ACCEPT
3.3、保存规则
iptables-save
完成上述命令我们就完成了开放指定的端口,但是如果此时服务器重启,上述规则就没有了,所以我们需要对规则进行一下持续化操作
3.4、安装iptables-persistent
sudo apt-get install iptables-persistent
3.5、持久化规则
sudo netfilter-persistent save
sudo netfilter-persistent reload
3.6、完成上述操作就可以永久打开我们需要的端口了
4、在我的本地 ubuntu 台式机上,打开一个终端,执行以下命令,订阅主题"test":
mosquitto_sub -h "159.176.23.180" -t "test" -v
mosquitto_sub
-c 设定‘clean session’为无效状态,这样一直保持订阅状态,即便是已经失去连接,如果再次连接仍旧能够接收的断开期间发送的消息。
-d 打印debug信息
-h 指定要连接的域名 默认为localhost
-i 指定clientId
-I 指定clientId前缀
-k keepalive 每隔一段时间,发PING消息通知broker,仍处于连接状态。 默认为60秒。
-q 指定希望接收到QoS为什么的消息 默认QoS为0
-R 不显示陈旧的消息
-t 订阅topic
-v 打印消息
-u 用户名
-P 密码
--will-payload 指定一个消息,该消息当客户端与broker意外断开连接时发出。该参数需要与--will-topic一起使用
--will-qos Will的QoS值。该参数需要与--will-topic一起使用
--will-retain 指定Will消息被当做一个retain消息(即消息被广播后,该消息被保留起来)。该参数需要与--will-topic一起使用
--will-topic 用户发送Will消息的topic
5、在我的本地ubuntu18.04台式机上,打开另外一个终端,执行以下命令,发布消息到主题 “test”:
mosquitto_pub -h "159.176.23.180" -t "test" -m "hello World"
mosquitto_pub
d 打印debug信息
-f 将指定文件的内容作为发送消息的内容
-h 指定要连接的域名 默认为localhost
-i 指定要给哪个clientId的用户发送消息
-I 指定给哪个clientId前缀的用户发送消息
-m 消息内容
-n 发送一个空(null)消息
-p 连接端口号
-q 指定QoS的值(0,1,2)
-t 指定topic
-u 指定broker访问用户
-P 指定broker访问密码
-V 指定MQTT协议版本
--will-payload 指定一个消息,该消息当客户端与broker意外断开连接时发出。该参数需要与--will-topic一起使用
--will-qos Will的QoS值。该参数需要与--will-topic一起使用
--will-retain 指定Will消息被当做一个retain消息(即消息被广播后,该消息被保留起来)。该参数需要与--will-topic一起使用
--will-topic 用户发送Will消息的topic
6、可以看到mosquitto_sub对应的终端,将及时收到 "hello World" 消息。
7、注意:使用mosquitto_sub、mosquitto_pub需要安装mqtt客户端,即:
sudo apt install mosquitto-clients
8、添加和修改配置
sudo service mosquitto stop #首先停止服务
#用户的局部配置文件放在: /etc/mosquitto/conf.d/目录下,并且这个目录下的所有以.conf后缀的文件都将被mosquitto作为配置文件,在启动时加载。
#在/etc/mosquitto/conf.d目录下,新建myconfig.conf配置文件
#在其中输入如下内容
#-------------------------------------------
# 关闭匿名访问,客户端必须使用用户名
allow_anonymous false
#指定 用户名-密码 文件
password_file /etc/mosquitto/pwfile.txt
#--------------------------------------------
9、创建一个MQTT服务器账户
假设用户名为:user1
在命令行运行:mosquitto_passwd -c /etc/mosquitto/pwfile.txt user1
回车后连续输入2次用户密码即可
10、重新启动mosquitto
sudo service mosquitto start #启动服务
三、测试mosquitto
在App Store下载MQTTool工具。
订阅一个消息,主题为test
发布主题为test的消息,点击发送后,点底部的Subscribe,看是否收到了推送。