物联网项目记录(1) 服务器配置(MQTT)

3.6k words

最近在移植之前物联网的竞赛项目的时候,重新整理了一下并记录。以便后面再次移植或者传给后人()。

需要:云服务器*1,镜像Ubuntu系统。

配置上,项目最初部署在华为云上,内存8G,带宽10M/s,硬盘120G(硬盘一般用不满,主要是内存和带宽)。

图传想要达到较好的质量,实测带宽10M/s是至少的,这样传递QQVGA的图像才能不明显卡顿。但是实际上图像处理可以放在边缘处理,就可以降低带宽需求。内存是考虑到运行深度学习模型需要的,但是也可以通过优化算法来降低需求。因此后期移植,我考虑的一个新的配置是内存4G,带宽6M/s,硬盘70G。

image-20240922022018669

开发环境搭建

远程连接服务器的推荐用Finalshell,集成了FTP和shell,非常好用。具体过程略。可以参考这篇文章,这个

这一步主要搭建EMQX,所以没什么代码量。后面面对前后端处理的HTTP服务器搭建时,就可以考虑用vscode的远程资源管理器来写代码。

EMQX配置

命令行按行逐个运行下列指令。

1
2
3
curl -s https://assets.emqx.com/scripts/install-emqx-deb.sh | sudo bash
sudo apt-get install emqx
sudo systemctl start emqx

如果你的端口已经全部开放,这时候浏览器输入<服务器ip>:18083就可以进入EMQX的后台管理系统。但是大部分云服务器是默认不打开这些端口的,需要在安全组配置。

EMQX需要哪些端口?服务器输入:

1
sudo lsof -i

找到所有是EMQX使用的端口:

image-20240922023609152

这些就是我们需要在云服务器厂商的后台开放的端口。进入云服务器厂商的后台,以腾讯云为例,找到“防火墙”(大概这个意思,华为云我记得是叫安全组)。

image-20240922023203850

点击添加规则,添加上述我们查询得知需要的端口。(为了图方便把所有端口都打开也行,但是不推荐)。

image-20240922023946096

现在浏览器输入<服务器ip>:18083,就可以看见后台了:

如果浏览器进不了这个网页后台,要么是服务器端口没有放开(上一步有问题),要么是浏览器自动解析成了https,而EMQX默认是http,这时候在浏览器输入<服务器ip>:18083,然后手动改成http就可以了。

image-20240922024128957

初始时,用户名是admin,密码是public

简单测试

在手头没有嵌入式设备的情况下,简单用python测试一下是否可行。

在本地电脑上新建一个项目文件夹(叫什么可以,我叫mqtt_tester),新建三个文件,config.yamlsender.pylistener.py,分别用来存储一些服务器和客户端配置文本、运行时负责模拟发送、运行时模拟接收。

预先需要pip一些包:

1
2
pip install paho-mqtt
pip install pyyaml

下面是config.yaml

1
2
3
4
5
6
7
8
server:
address: "<服务器ip>" # MQTT服务器地址
port: 1883 # MQTT服务器端口
topics: # 可订阅主题
- "mqtt/test" # 测试主题

client:
name: "mqtt_tester"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
"""
sender.py
模拟客户端,测试MQTT服务器收发消息
"""

import os
import paho.mqtt.client as mqtt
import yaml

# 获取当前脚本文件的绝对路径,然后获取同目录下的config.yaml文件的路径
current_dir = os.path.dirname(os.path.abspath(__file__))
config_path = os.path.join(current_dir, 'config.yaml')
with open(config_path, 'r', encoding='utf-8') as file:
config = yaml.safe_load(file)
broker_address = config['server']['address']
broker_port = config['server']['port']

def on_connect(client, userdata, flags, rc):
print(f"Connected with result code {rc}")

client = mqtt.Client()
client.on_connect = on_connect
client.username_pw_set(config['client']['name'])
client.connect(broker_address, broker_port, 60)

client.loop_start()

while True:
topic = input("请输入主题: ")
message = input("请输入消息内容: ")#.encode('gbk') #后面可以选编码格式,简单测试不需要
client.publish(topic, message)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
"""
listener.py
测试MQTT监听程序
"""

import os
import paho.mqtt.client as mqtt
import yaml

current_dir = os.path.dirname(os.path.abspath(__file__))
config_path = os.path.join(current_dir, 'config.yaml')

with open('config.yaml', 'r', encoding='utf-8') as file:
config = yaml.safe_load(file)
MQTT_SERVER = config['server']['address']
MQTT_PORT = config['server']['port']
MQTT_TOPIC = config['server']['topics']

def on_message(client, userdata, msg):
try:
message = msg.payload.decode('utf-8') # 尝试用UTF-8解码
except UnicodeDecodeError:
message = msg.payload.decode('gbk') # 如果失败,改用GBK解码
topic = msg.topic
print(f"Received message '{message}' on topic '{topic}'")

def on_connect(client, userdata, flags, rc):
print("Connected with result code "+str(rc))
for topic in MQTT_TOPIC:
client.subscribe(topic)

if __name__ == '__main__':
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message

client.username_pw_set(config['client']['name'])
client.connect(MQTT_SERVER, MQTT_PORT, 60)

client.loop_forever()

同时运行上述两个sender.pylistener.py,在前者的控制台中输入主题和消息内容,切换到后者的控制台,就可以看见已经收到了消息:

image-20240922030511802

image-20240922030521758

不要关闭控制台,打开前面的EMQX后台网页,进入客户端,可以看见两个连接的客户端。

image-20240922030856835