看了一个澳国立的项目,感觉中规中矩,练习强度很好,MQTT是物联网领域非常通用的协议。用来非同步传输消息,因同步传输可能出现网络收敛。那么我们来看看MQTT的1工作机制

MQTT工作流程

MQTT有三个部分,分别为subscriber, broker, publisher。这三个部分我们可以理解为client, proxy, server。其实这个类比真的很恰当。

只不过他们最大的区别就是socket连接为TCP同步传输,而我们的MQTT协议是异步传输,可以由broker来控制。

subscriber

用来订阅信息,也就是在发送的信息前面加个标头topic,叫做主题,接受信息的时候,只能接收publisher公布的标头与前面topic相吻合的信息。注:订阅的消息有Qos的性质,也就是可以订阅不同服务质量的信息。

QOS在MQTT中分为四种:

0:表示最多一次

1:至少一次

2:一次

3:预留

broker

用来做中间人,也就是代理服务器。接收来自subcriber的订阅,然后等待publisher端的发布,一旦发布相同topic,broker就把此消息发回给subscriber,并且根据订阅的服务质量来发送。

publisher

刚才其实已经提到了它的作用,用来发布被订阅的主题的消息。

这里介绍三种实践方式

1.windows系统,通过MQTT云服务器来实现

1
https://cloud.emqx.com/

可以登陆这个网站,提供14天免费的MQTT服务器,后期包月的话价格也不贵,可以接受。

网站有具体的配置导引,我们只需要下载一个broker,也就是MQTTX,直接去搜索一下下载即可。

打开MQTTX之后可以连接我们购买的云服务器,即可开启MQTT之旅。详细配置都在https://cloud.emqx.com/的导引中。

image-20220510013239385

我们可以看到,我们可以订阅一个topic为test的消息,名字取为hello在右侧为消息的发送,相当于publisher,比如我们发送topic为test的消息(在右下msg上面那一行小字,test,不容易被发现)然后灰色回显为我们的subscriber的接收。

2.通过docker来部署mosquitto服务

因为我们知道docker也是linux内核,在windows中命令的概念不强,我们如果把主机开启当作实践服务器,要开启mosquitto服务,先选择用docker来实现。

下载安装docker的过程省略。

建议在ubuntu虚拟机上进行,因为主机docker非常占用c盘空间。

1
2
3
4
5
6
docker pull eclipse-mosquitto
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
eclipse-mosquitto latest 4ded7c622999 9 days ago 6.28MB

#首先拉取了镜像
1
2
3
4
mkdir -p /mosquitto/config#参数p为自动生成不存在的目录
mkdir -p /mosquitto/data
mkdir -p /mosquitto/log
#建立了配置目录

然后建立配置文件

1
2
3
4
5
vi /mosquitto/config/mosquitto.conf
# 写入以下内容
persistence true
persistence_location /mosquitto/data
log_dest file /mosquitto/log/mosquitto.log

为目录配置权限

1
2
chmod -R 755 /mosquitto
chmod -R 777 /mosquitto/log #日志目录要最大权限

然后建立docker容器,也就是创建了一个mosquitto镜像下的迷你linux系统

1
2
docker run -it --name=mosquitto --privileged  -p 1883:1883 -p 9001:9001 -v /mosquitto/config:/mosquitto/config/ -v /mosquitto/data/:/mosquitto/data -v /mosquitto/log/:/mosquitto/log -d  eclipse-mosquitto
#这里1883:1883表示将docker容器的1883端口映射到宿主机的1883端口,我们如果不设置IP,默认为0.0.0.0:1883:1883也就是主机的1883对应docker的1883,如果设置为127.0.0.1:1883:1883则使用MQTT连接时,只能允许虚拟机内自己连接,不能用局域网内其他主机去输入局域网IP连接,愿意在于局域网IP和环回地址的区别,详见我博客的环回地址文章。

我们现在外面配置权限

1
2
3
4
5
6
7
8
vim  /mosquitto/config/mosquitto.conf
#然后添加以下内容

# 关闭匿名模式
allow_anonymous false
# 指定密码文件
password_file /mosquitto/config/pwfile.conf

然后进入容器

1
2
3
4
5
6
7
docker ps#查看容器运行状态
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3fdbb2bc353c eclipse-mosquitto "/docker-entrypoint.…" About an hour ago Up About an hour 0.0.0.0:1883->1883/tcp, 0.0.0.0:9001->9001/tcp mosquitto
56571b7ba421 zookeeper "/docker-entrypoint.…" 2 months ago Up 2 hours 0.0.0.0:2181->2181/tcp, 0.0.0.0:2888->2888/tcp, 0.0.0.0:3888->3888/tcp, 8080/tcp zk

docker exec -it 3fdbb2bc353c sh#进入容器,这里使用的是sh而不是/bin/bash因为用的命令时基于sh的,并不是bash的,其他种类还有zsh等等

然后配置用户名和密码

1
2
3
4
5
6
7
#对于passworf_file,可以复制一份模板,或者创建一个空文件
touch /mosquitto/config/pwfile.conf
chmod -R 755 /mosquitto/config/pwfile.conf

# 使用mosquitto_passwd命令创建用户,第一个test是用户名,第二个test2019是密码
mosquitto_passwd -b /mosquitto/config/pwfile.conf test test2019

然后退出容器

1
exit

然后重启容器

1
docker restart 3fdbb2bc353c  

然后我们可以使用MQTTX进行连接

至于安装MQTTX到linux的方法,先找到下载链接,注意linux普遍支持deb后缀的可执行打包文件。

1
wget http://xxxxx.deb#下载即可

注意自己提前新建一个文件夹,不要都下载根目录下。。

然后解压安装

1
sudo dpkg -i xxx.deb

image-20220510014713423

默认内容不该,自己填好IP地址和我们设定的端口1883输入用户名密码,连接即可。

3.利用ubuntu直接当作服务器,开启mosquitto服务

首先安装mosquitto服务

1
2
3
4
5
6
7
# 安装mosquitto
sudo apt-get install mosquitto
# 安装客户端
sudo apt-get install mosquitto-clients
# 安装设备端
sudo apt-get install mosquitto-dev

安装好了一套,上述就是服务,加上订阅端,加上发布端。

1
mosquitto -c /etc/mosquitto/mosquitto.conf

按照配置文件运行服务

然后我们查看服务状态

1
systemctl status mosquitto

开启关闭服务

1
systemctl start/stop mosquitto

这里介绍一下

1
2
3
systemctl命令:是一个systemd工具,主要负责控制systemd系统和服务管理器。
service命令:可以启动、停止、重新启动和关闭系统服务,还可以显示所有系统服务的当前状态。
chkconfig命令:是管理系统服务(service)的命令行工具。所谓系统服务(service),就是随系统启动而启动,随系统关闭而关闭的程序。

三者都用来开启系统服务,不过,建议用第一个。因为后两个可能会出现重加载等问题。第一个是后两个的集合。

然后开始使用协议

订阅者订阅主题

1
mosquitto_sub -v -t hello#topic为hello

然后可以在主题下等待发布者发布内容。

打开另一个终端作为发布者

1
mosquitto_pub -t hello -m world#发布内容

这是最基本的通过命令行,此时也可以通过MQTTX,我们可以在ubuntu用MQTTX连接IP地址为127.0.0.1即可。

然后还可以在本机,用MQTTX连接虚拟机ubuntu的局域网地址,其实这就真正起到了远程物联网的作用。