物联网系统三层架构解析

主要就是3层架构

1,设备层

配置mqtt链接

使用MQTT Broker服务器

2,中间层,用一般服务器(中间协调)

(负责协议转换与接口封装)

3,前端层(面向用户)

采用webSocket与中间层保持长链接

你可以把这个架构想象成一个新闻系统:

设备层:是各地的记者。他们用特定的方式(MQTT)将写好的新闻稿(传感器数据)发送到新闻总社(MQTT Broker)。

MQTT Broker:是新闻总社。它接收所有记者的稿件,并按照版面(主题)分类存放。

中间层:是你的新闻App的后台。它派人长期驻守在新闻总社,订阅你感兴趣的版面(比如"科技版")。一旦有新的科技新闻,它就立刻抓取过来,然后通过App的推送系统(WebSocket)发到你的手机上。

前端层:就是你手机上的新闻App界面。它和后台保持着推送连接,所以新闻一来,你的App界面就会立刻弹出通知,内容实时更新。

其实这里面比较难理解的就是,设备层(MQTT Broker服务器)和中间层的一般服务器的作用,

以下是2者的区别,

其实感觉最大的区别就是是否轻量,实时

1,一般服务器

角色:服务提供者 和 逻辑处理中心。

沟通是一对一的,并且通常是你主动发起的。

提供稳定、安全、复杂的业务服务

连接方式,短连接

典型协议。HTTP, HTTPS, TCP Socket

2,MQTT Broker:

角色:消息中转站 或 信息分发中心

沟通可以是一对多,对多个订阅者

像一个微信群群主或电台。它自己不产生消息,而是负责把某些人(发布者)发出的消息,转发给所有关心这个消息的人(订阅者)。沟通是一对多的,并且是基于兴趣的。

实现轻量级、低功耗、高实时性的机器与机器之间的通信

连接方式,长连接

典型协议 MQTT协议(基于TCP)

作用

1,消息路由与中转(核心功能)

因为板子或者传感器本身不适合处理太多逻辑,方便设备与设备之间通讯,设备与中间层通讯。
2,会话管理与离线消息

当订阅者设备网络不稳定或暂时离线时,Broker可以(根据设置的服务质量等级)为它保存消息。等设备重新上线后,Broker会将这些离线期间的消息重新发送给它。

这保证了重要数据在弱网络环境下的可靠传输。

二,其实不要,"一般服务器"也行,

只不过复杂的物联网系统,还是不可或缺

"一般服务器"在物联网系统中的作用

虽然消息传递不需要它,但一个完整的物联网系统仍然离不开一般服务器。它们各司其职,协同工作。

一般服务器在物联网系统中负责 "管理"和"智能" 部分:

  1. 设备管理:
    * 一般服务器提供一个Web界面或API,让你注册新设备、管理设备密钥。
    * 它可能负责向设备和手机APP下发MQTT Broker的连接地址。
  2. 数据持久化与智能分析:
    * MQTT Broker的核心是传递消息,通常不长期保存数据。
    * 这时,我们需要一个"订阅者"来将数据存入数据库。这个订阅者常常就是你的一般服务器!
    * 新数据流:传感器 -> MQTT Broker -> 一般服务器(订阅者) -> 数据库
    * 一般服务器存入数据后,可以进行复杂分析、生成报表、训练AI模型等。
  3. 提供业务接口:
    * 你的手机APP可能需要查看历史温度曲线。这个请求不会通过MQTT,而是直接HTTP请求到一般服务器,服务器再从数据库查询后返回。
  4. 发送控制命令:
    * 当你想通过手机远程打开空调时,手机APP可以通过HTTP请求告诉一般服务器。
    * 一般服务器然后作为MQTT发布者,向主题 app/command 发布一条 "turn_on_ac" 的消息。
    * 空调,作为 app/command 的订阅者,从Broker收到消息后执行开机。

三,前端层

职责:采用webSocket与中间层保持长链接

这是用户直接交互的界面,通常是一个运行在浏览器中的网页应用(Web App)。

采用WebSocket:WebSocket是一种在单个TCP连接上进行全双工通信的协议。它非常适合需要服务器主动向客户端推送数据的场景。

与中间层保持长链接:

前端通过JavaScript的 WebSocket API,与中间层建立一个持久的长连接。

一旦连接建立,中间层就可以在任何需要的时候,立即将收到的设备数据通过这个连接推送给前端,前端页面无需刷新就能实时更新显示(比如图表跳动、数字变化)。

四,mqtt Broker开发语言

  • 一般服务器开发:选择开发效率高的语言(Java/PHP/Node.js/Python等)
  • MQTT Broker开发:选择网络性能极致的语言(Erlang/C/Java/Go等)

五,进阶功能

复制代码
进阶功能
1. OTA 远程更新
可以让 ESP32 通过 WiFi 接收代码更新,无需物理连接。
2. 低功耗模式
使用深度睡眠模式节省电量,适合电池供电场景。
3. 数据加密
使用 TLS/SSL 加密 MQTT 通信,提高安全性。
4. 断线重连机制
增强网络异常时的稳定性。

附,一个板子,接mqtt的源码

复制代码
#include <WiFi.h>
#include <PubSubClient.h>

// WiFi 配置
const char* ssid = "你的WiFi名称";
const char* password = "你的WiFi密码";

// MQTT 配置
const char* mqtt_broker = "broker.emqx.io";  // 免费MQTT服务器
const int mqtt_port = 1883;
const char* topic = "esp32/sensor/data";     // 主题名称
const char* mqtt_username = "";              // 用户名(公共服务器通常为空)
const char* mqtt_password = "";              // 密码

// 创建客户端对象
WiFiClient espClient;
PubSubClient client(espClient);

// 设备ID(用于区分多个设备)
String clientId = "ESP32Client-" + String(random(0xffff), HEX);

void setup() {
  Serial.begin(115200);
  
  // 1. 连接 WiFi
  setup_wifi();
  
  // 2. 配置 MQTT
  client.setServer(mqtt_broker, mqtt_port);
  client.setCallback(callback);  // 设置接收消息的回调函数
  
  // 3. 连接 MQTT Broker
  connect_mqtt();
}

void loop() {
  // 保持 MQTT 连接
  if (!client.connected()) {
    connect_mqtt();
  }
  client.loop();  // 处理MQTT消息
  
  // 每5秒发布一次数据
  static unsigned long lastMsg = 0;
  if (millis() - lastMsg > 5000) {
    lastMsg = millis();
    publish_sensor_data();
  }
}

// 连接 WiFi
void setup_wifi() {
  delay(10);
  Serial.println();
  Serial.print("连接WiFi: ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi连接成功");
  Serial.println("IP地址: ");
  Serial.println(WiFi.localIP());
}

// 连接 MQTT Broker
void connect_mqtt() {
  while (!client.connected()) {
    Serial.print("连接MQTT Broker...");
    
    if (client.connect(clientId.c_str(), mqtt_username, mqtt_password)) {
      Serial.println("连接成功!");
      
      // 订阅主题(如果需要接收指令)
      client.subscribe("esp32/control");
    } else {
      Serial.print("失败, rc=");
      Serial.print(client.state());
      Serial.println(" 5秒后重试...");
      delay(5000);
    }
  }
}

// 接收消息的回调函数(当收到订阅的消息时调用)
void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("收到消息 [");
  Serial.print(topic);
  Serial.print("]: ");
  
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
  
  // 这里可以处理接收到的控制指令
  // 例如:开关LED、重启设备等
}

// 发布传感器数据
void publish_sensor_data() {
  // 模拟传感器数据(实际中从这里读取真实传感器)
  float temperature = random(200, 300) / 10.0;  // 20.0-30.0°C
  float humidity = random(400, 800) / 10.0;     // 40.0-80.0%
  
  // 创建JSON格式数据
  String message = "{";
  message += "\"deviceId\":\"" + clientId + "\",";
  message += "\"temperature\":" + String(temperature) + ",";
  message += "\"humidity\":" + String(humidity) + ",";
  message += "\"timestamp\":" + String(millis());
  message += "}";
  
  // 发布消息
  if (client.publish(topic, message.c_str())) {
    Serial.println("数据发布成功: " + message);
  } else {
    Serial.println("数据发布失败");
  }
}
相关推荐
TDengine (老段)6 分钟前
TDengine Python 连接器入门指南
大数据·数据库·python·物联网·时序数据库·tdengine·涛思数据
老前端的功夫22 分钟前
TypeScript 类型魔术:模板字面量类型的深层解密与工程实践
前端·javascript·ubuntu·架构·typescript·前端框架
min1811234561 小时前
PC端零基础跨职能流程图制作教程
大数据·人工智能·信息可视化·架构·流程图
静听松涛1331 小时前
中文PC端多人协作泳道图制作平台
大数据·论文阅读·人工智能·搜索引擎·架构·流程图·软件工程
专业开发者2 小时前
借助安全返场方案提升智慧建筑能效的新机遇
物联网·安全
匠在江湖3 小时前
裸机单片机任务调度器实现:基于规范分层(COM/APP/SRV/DRV)架构,(附 任务调度器 / 微秒延时函数 / 串口重定向 源码)
单片机·嵌入式硬件·架构
gaize12133 小时前
服务器怎么选择与配置才能满足企业需求?
运维·服务器·架构
WZGL12303 小时前
当银发遇见数字浪潮:物联网医疗如何让“养老”蝶变为“享老”
物联网
加个鸡腿儿3 小时前
经验分享2:SSR 项目中响应式组件的闪动陷阱与修复实践
前端·css·架构
一条咸鱼_SaltyFish4 小时前
[Day15] 若依框架二次开发改造记录:定制化之旅 contract-security-ruoyi
java·大数据·经验分享·分布式·微服务·架构·ai编程